From 3d417836ab5f0683d43a2b202b22125e6fc82a94 Mon Sep 17 00:00:00 2001 From: Max Krummenacher Date: Wed, 8 May 2019 16:03:01 +0200 Subject: tinycompress: import recipe Import from meta-fsl-bsp-release @ sumo-4.14.78-1.0.0_ga Signed-off-by: Max Krummenacher --- .../0001-tinycompress-Add-id3-decoding.patch | 1001 ++++++++++++++++++++ .../tinycompress/tinycompress_1.1.6.bb | 13 + 2 files changed, 1014 insertions(+) create mode 100755 recipes-multimedia/tinycompress/tinycompress/0001-tinycompress-Add-id3-decoding.patch create mode 100644 recipes-multimedia/tinycompress/tinycompress_1.1.6.bb (limited to 'recipes-multimedia') diff --git a/recipes-multimedia/tinycompress/tinycompress/0001-tinycompress-Add-id3-decoding.patch b/recipes-multimedia/tinycompress/tinycompress/0001-tinycompress-Add-id3-decoding.patch new file mode 100755 index 0000000..f578148 --- /dev/null +++ b/recipes-multimedia/tinycompress/tinycompress/0001-tinycompress-Add-id3-decoding.patch @@ -0,0 +1,1001 @@ +From 16f6b7a5baec41f18fde75fd311fb988e3c31810 Mon Sep 17 00:00:00 2001 +From: Shengjiu Wang +Date: Fri, 13 Jul 2018 18:13:24 +0800 +Subject: [PATCH] tinycompress: Add id3 decoding + +Signed-off-by: Shengjiu Wang +--- + include/tinycompress/id3_tag_decode.h | 198 +++++++++++ + src/utils/Makefile.am | 2 +- + src/utils/cplay.c | 88 +++++ + src/utils/id3_tag_decode.c | 642 ++++++++++++++++++++++++++++++++++ + 4 files changed, 929 insertions(+), 1 deletion(-) + create mode 100644 include/tinycompress/id3_tag_decode.h + create mode 100644 src/utils/id3_tag_decode.c + +diff --git a/include/tinycompress/id3_tag_decode.h b/include/tinycompress/id3_tag_decode.h +new file mode 100644 +index 0000000..1a911d7 +--- /dev/null ++++ b/include/tinycompress/id3_tag_decode.h +@@ -0,0 +1,198 @@ ++/* ++ * Copyright (c) 2006-2017 Cadence Design Systems, Inc. ++ * Copyright 2018 NXP ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included ++ * in all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY ++ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, ++ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE ++ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ */ ++ ++/****************************************************************** ++ * file name : id3_tag_decode.h ++ * ++ * description : stores typedefs of structures specific to MP3 tag ++ * ++ * revision history: ++ * 29 04 2004 DK creation ++ *****************************************************************/ ++ ++#ifndef ID3_TAG_DECODE_H ++#define ID3_TAG_DECODE_H ++ ++typedef signed char WORD8; ++typedef signed char * pWORD8; ++typedef unsigned char UWORD8; ++typedef unsigned char * pUWORD8; ++ ++typedef signed short WORD16; ++typedef signed short * pWORD16; ++typedef unsigned short UWORD16; ++typedef unsigned short * pUWORD16; ++ ++typedef signed int WORD24; ++typedef signed int * pWORD24; ++typedef unsigned int UWORD24; ++typedef unsigned int * pUWORD24; ++ ++typedef signed int WORD32; ++typedef signed int * pWORD32; ++typedef unsigned int UWORD32; ++typedef unsigned int * pUWORD32; ++ ++typedef void VOID; ++typedef void * pVOID; ++ ++typedef signed int BOOL; ++typedef unsigned int UBOOL; ++typedef signed int FLAG; ++typedef unsigned int UFLAG; ++typedef signed int LOOPIDX; ++typedef unsigned int ULOOPIDX; ++typedef signed int WORD; ++typedef unsigned int UWORD; ++ ++#define MAX_TAG_FRAME_SIZE 100 ++ ++#define ID3V1 (0x544147) /* 0x544147 is TAG in WORD8 */ ++ ++#define ID3V2 (0x494433) /* 0x494433 is ID3 in WORD8 */ ++ ++/* ++ * structure corresponding to ID3 tag v1 header. ++ * this structure has all the field corresponding to ID3 tag v1 header. ++ */ ++ ++typedef struct { ++ WORD32 tag; // 3 bytes ++ ++ WORD16 version; // 2 bytes ++ ++ WORD8 flag; //1 byte ++ ++ WORD32 size; //4 bytes ++ ++} id3_v2_header_struct; ++ ++/* structure which will store the frame data and ++ * also put a limit max data to be stored ++ */ ++typedef struct { ++ WORD8 frame_data[MAX_TAG_FRAME_SIZE]; ++ ++ WORD32 max_size; //4 bytes ++ ++ WORD16 tag_present; ++ ++ WORD16 exceeds_buffer_size; ++ ++} id3_v2_frame_struct; ++ ++/* ++ * structure corresponding to ID3 tag v2. ++ * this structure has some of the field corresponding to ID3 tag v2. ++ * if user wants to read some more tag information from ++ * the MP3 file, he can add that field in this structure and pass address ++ * of that element to get_inf function in id3_tag_decode.c under the ++ * corresponding field frame header. few fields which are needed are already ++ * populated by reading from the TAG header. ++ */ ++typedef struct { ++ id3_v2_frame_struct album_movie_show_title; ++ ++ id3_v2_frame_struct composer_name; ++ ++ id3_v2_frame_struct content_type; ++ ++ id3_v2_frame_struct encoded_by; ++ ++ id3_v2_frame_struct lyricist_text_writer; ++ ++ id3_v2_frame_struct content_group_description; ++ ++ id3_v2_frame_struct title_songname_content_description; ++ ++ id3_v2_frame_struct medxa_type; ++ ++ id3_v2_frame_struct original_album_movie_show_title; ++ ++ id3_v2_frame_struct original_filename; ++ ++ id3_v2_frame_struct original_lyricist_text_writer; ++ ++ id3_v2_frame_struct original_artist_performer; ++ ++ id3_v2_frame_struct file_owner_licensee; ++ ++ id3_v2_frame_struct lead_performer_soloist; ++ ++ id3_v2_frame_struct publisher; ++ ++ id3_v2_frame_struct private_frame; ++ ++ id3_v2_frame_struct other_info; ++ ++ id3_v2_header_struct id3_v2_header; ++ ++ WORD32 header_end; ++ ++ WORD32 bytes_consumed; ++ ++} id3v2_struct; ++ ++/* ++ * structure corresponding to ID3 tag v1. ++ * this structure has all the field corresponding to ID3 tag v1. ++ */ ++typedef struct { ++ WORD8 song_title[30]; //30 word8acters ++ ++ WORD8 artist[30]; //30 word8acters ++ ++ WORD8 album[30]; //30 word8acters ++ ++ WORD8 year[4]; //4 word8acters ++ ++ WORD8 comment[30]; //30 word8acters ++ ++ WORD8 genre[1]; //1 byte ++ ++} id3v1_struct; ++ ++WORD32 get_info(const char *inp_buffer, ++ unsigned int avail_inp, ++ WORD32 tag_size, ++ id3_v2_frame_struct *dest); ++ ++WORD32 search_id3_v2(UWORD8 *buffer); ++ ++WORD32 decode_id3_v2(const char *const buffer, ++ id3v2_struct *id3v2, ++ WORD32 continue_flag, ++ WORD32 insize); ++ ++WORD32 get_id3_v2_bytes(UWORD8 *buffer); ++ ++WORD32 get_v1_info(UWORD8 *buffer, id3v1_struct *id3v1); ++ ++WORD32 search_id3_v1(UWORD8 *buffer); ++ ++WORD32 decode_id3_v1(UWORD8 *buffer, id3v1_struct *id3v1); ++ ++void init_id3v2_field(id3v2_struct *id3v2); ++ ++#endif +diff --git a/src/utils/Makefile.am b/src/utils/Makefile.am +index 1b996d4..e813689 100644 +--- a/src/utils/Makefile.am ++++ b/src/utils/Makefile.am +@@ -1,6 +1,6 @@ + bin_PROGRAMS = cplay crecord + +-cplay_SOURCES = cplay.c ++cplay_SOURCES = cplay.c id3_tag_decode.c + crecord_SOURCES = crecord.c + + cplay_CFLAGS = -I$(top_srcdir)/include +diff --git a/src/utils/cplay.c b/src/utils/cplay.c +index 87863a3..2a52b52 100644 +--- a/src/utils/cplay.c ++++ b/src/utils/cplay.c +@@ -72,6 +72,7 @@ + #include "sound/compress_params.h" + #include "tinycompress/tinycompress.h" + #include "tinycompress/tinymp3.h" ++#include "tinycompress/id3_tag_decode.h" + + static int verbose; + static const unsigned int DEFAULT_CODEC_ID = SND_AUDIOCODEC_PCM; +@@ -245,12 +246,97 @@ int main(int argc, char **argv) + exit(EXIT_SUCCESS); + } + ++void shift_buffer(char *buf, int buf_size, int bytes_consumed) ++{ ++ int i; ++ ++ if (bytes_consumed <= 0) ++ return; ++ ++ for (i = 0; i < buf_size - bytes_consumed; i++) ++ buf[i] = buf[i + bytes_consumed]; ++} ++ ++void parse_id3(FILE *file, int *offset) { ++ /* ID3 tag specific declarations */ ++ unsigned char id3_buf[128]; ++ unsigned char id3v2_buf[4096]; ++ signed int id3_v1_found = 0, id3_v1_decoded = 0; ++ signed int id3_v2_found = 0, id3_v2_complete = 0; ++ signed int i_bytes_consumed = 0; ++ signed int i_fread_bytes; ++ id3v1_struct id3v1; ++ id3v2_struct id3v2; ++ ++ { ++ fseek(file, -128, SEEK_END); ++ fread(id3_buf, 1, 128, file); ++ ++ /* search for ID3V1 */ ++ id3_v1_found = search_id3_v1(id3_buf + 0); ++ if (id3_v1_found) { ++ /* if ID3V1 is found, decode ID3V1 */ ++ decode_id3_v1(id3_buf + 3, &id3v1); ++ id3_v1_decoded = 1; ++ } ++ fseek(file, 0, SEEK_SET); ++ } ++ ++ { ++ signed int flag = 0; ++ signed int continue_flag = 0; ++ ++ i_fread_bytes = fread(id3v2_buf, ++ sizeof(char), 0x1000, file); ++ ++ /* search for ID3V2 */ ++ id3_v2_found = ++ search_id3_v2(id3v2_buf); ++ ++ if (id3_v2_found) { ++ /* initialise the max fields */ ++ init_id3v2_field(&id3v2); ++ ++ while (!id3_v2_complete && id3_v2_found) { ++ /* if ID3V2 is found, decode ID3V2 */ ++ id3_v2_complete = decode_id3_v2((const char *const)id3v2_buf, ++ &id3v2, continue_flag, i_fread_bytes); ++ ++ if (!id3_v2_complete) { ++ continue_flag = 1; ++ i_bytes_consumed = id3v2.bytes_consumed; ++ ++ fseek(file, i_bytes_consumed, SEEK_SET); ++ ++ i_fread_bytes = fread(id3v2_buf, ++ sizeof(unsigned char), 0x1000, file); ++ if (i_fread_bytes <= 0) { ++ return; ++ } ++ } ++ } ++ ++ if (id3_v2_complete) { ++ i_bytes_consumed = id3v2.bytes_consumed; ++ fseek(file, i_bytes_consumed, SEEK_SET); ++ } ++ } ++ } ++ ++ *offset = i_bytes_consumed; ++} ++ + void get_codec_mp3(FILE *file, struct compr_config *config, + struct snd_codec *codec) + { + size_t read; + struct mp3_header header; + unsigned int channels, rate, bits; ++ int offset = 0; ++ ++ parse_id3(file, &offset); ++ ++ fseek(file, offset, SEEK_SET); + + read = fread(&header, 1, sizeof(header), file); + if (read != sizeof(header)) { +@@ -279,6 +365,8 @@ void get_codec_mp3(FILE *file, struct compr_config *config, + codec->level = 0; + codec->ch_mode = 0; + codec->format = 0; ++ ++ fseek(file, offset, SEEK_SET); + } + + void get_codec_iec(FILE *file, struct compr_config *config, +diff --git a/src/utils/id3_tag_decode.c b/src/utils/id3_tag_decode.c +new file mode 100644 +index 0000000..393967a +--- /dev/null ++++ b/src/utils/id3_tag_decode.c +@@ -0,0 +1,642 @@ ++/* ++ * Copyright (c) 2006-2017 Cadence Design Systems, Inc. ++ * Copyright 2018 NXP ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included ++ * in all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY ++ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, ++ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE ++ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ */ ++#include ++#include "tinycompress/id3_tag_decode.h" ++ ++#define CHAR4(c1, c2, c3, c4) \ ++ (int)(((unsigned char)(c1) << 24) | \ ++ ((unsigned char)(c2) << 16) | \ ++ ((unsigned char)(c3) << 8) | \ ++ ((unsigned char)c4)) ++ ++#ifndef MSVC_BUILD ++unsigned int umin(unsigned int a, unsigned int b) ++{ ++ return (a < b ? a : b); ++} ++ ++#else ++unsigned int umin(unsigned int a, unsigned int b) ++{ ++ return (a < b ? a : b); ++} ++#endif ++ ++/*********************************************************** ++ * function name : display ++ * ++ * description : display ID3 tag contents. ++ * ++ * arguments : input parameters ++ * ++ * values returned : 0 ++ ***********************************************************/ ++ ++static void display2(const id3_v2_frame_struct * const src, ++ int size, ++ const char * const disp) ++{ ++ int j; ++ ++ ++ for (j = 0; j < size; j++) { ++ int c = src->frame_data[j]; ++ ++ if (c) { ++ if (!isprint(c)) ++ break; ++ } ++ } ++} ++ ++static VOID display1(WORD8 src[], WORD32 size, WORD8 disp[]) ++{ ++ WORD32 j; ++ ++ for (j = 0; j < size ; j++) { ++ int c = src[j]; ++ ++ if (c) { ++ if (!isprint(c)) ++ break; ++ } ++ } ++} ++ ++/***************************************************************** ++ * function name : init_id3_header ++ * ++ * description : initialise the max filed size of teh farem. ++ * ++ * arguments : input parameters ++ * ++ * values returned : 0 ++ ****************************************************************/ ++ ++VOID init_id3v2_field(id3v2_struct *id3v2) ++{ ++ id3v2->album_movie_show_title.max_size = MAX_TAG_FRAME_SIZE; ++ id3v2->composer_name.max_size = MAX_TAG_FRAME_SIZE; ++ id3v2->content_type.max_size = MAX_TAG_FRAME_SIZE; ++ id3v2->encoded_by.max_size = MAX_TAG_FRAME_SIZE; ++ id3v2->lyricist_text_writer.max_size = MAX_TAG_FRAME_SIZE; ++ id3v2->content_group_description.max_size = MAX_TAG_FRAME_SIZE; ++ id3v2->title_songname_content_description.max_size = MAX_TAG_FRAME_SIZE; ++ id3v2->medxa_type.max_size = MAX_TAG_FRAME_SIZE; ++ id3v2->original_album_movie_show_title.max_size = MAX_TAG_FRAME_SIZE; ++ id3v2->original_filename.max_size = MAX_TAG_FRAME_SIZE; ++ id3v2->original_lyricist_text_writer.max_size = MAX_TAG_FRAME_SIZE; ++ id3v2->original_artist_performer.max_size = MAX_TAG_FRAME_SIZE; ++ id3v2->file_owner_licensee.max_size = MAX_TAG_FRAME_SIZE; ++ id3v2->lead_performer_soloist.max_size = MAX_TAG_FRAME_SIZE; ++ id3v2->publisher.max_size = MAX_TAG_FRAME_SIZE; ++ id3v2->private_frame.max_size = MAX_TAG_FRAME_SIZE; ++ id3v2->other_info.max_size = MAX_TAG_FRAME_SIZE; ++ ++ /* resetting the flag to indicate presese of frame */ ++ id3v2->album_movie_show_title.tag_present = 0; ++ id3v2->composer_name.tag_present = 0; ++ id3v2->content_type.tag_present = 0; ++ id3v2->encoded_by.tag_present = 0; ++ id3v2->lyricist_text_writer.tag_present = 0; ++ id3v2->content_group_description.tag_present = 0; ++ id3v2->title_songname_content_description.tag_present = 0; ++ id3v2->medxa_type.tag_present = 0; ++ id3v2->original_album_movie_show_title.tag_present = 0; ++ id3v2->original_filename.tag_present = 0; ++ id3v2->original_lyricist_text_writer.tag_present = 0; ++ id3v2->original_artist_performer.tag_present = 0; ++ id3v2->file_owner_licensee.tag_present = 0; ++ id3v2->lead_performer_soloist.tag_present = 0; ++ id3v2->publisher.tag_present = 0; ++ id3v2->private_frame.tag_present = 0; ++ id3v2->other_info.tag_present = 0; ++ ++ /* resetting the flag which indicates that size of the frame has ++ * exceeded the max buffer size ++ */ ++ id3v2->album_movie_show_title.exceeds_buffer_size = 0; ++ id3v2->composer_name.exceeds_buffer_size = 0; ++ id3v2->content_type.exceeds_buffer_size = 0; ++ id3v2->encoded_by.exceeds_buffer_size = 0; ++ id3v2->lyricist_text_writer.exceeds_buffer_size = 0; ++ id3v2->content_group_description.exceeds_buffer_size = 0; ++ id3v2->title_songname_content_description.exceeds_buffer_size = 0; ++ id3v2->medxa_type.exceeds_buffer_size = 0; ++ id3v2->original_album_movie_show_title.exceeds_buffer_size = 0; ++ id3v2->original_filename.exceeds_buffer_size = 0; ++ id3v2->original_lyricist_text_writer.exceeds_buffer_size = 0; ++ id3v2->original_artist_performer.exceeds_buffer_size = 0; ++ id3v2->file_owner_licensee.exceeds_buffer_size = 0; ++ id3v2->lead_performer_soloist.exceeds_buffer_size = 0; ++ id3v2->publisher.exceeds_buffer_size = 0; ++ id3v2->private_frame.exceeds_buffer_size = 0; ++ id3v2->other_info.exceeds_buffer_size = 0; ++ ++ id3v2->bytes_consumed = 0; ++ id3v2->header_end = 0; ++} ++ ++/*************************************************************** ++ * function name : search_id3_v2 ++ * ++ * description : finds if ID3V2 starts at the start of given buffer. ++ * ++ * arguments : input parameters ++ * buffer input buffer ++ * ++ * values returned : FLAG 1: ID3 found 0: ID3 not found ++ ***************************************************************/ ++WORD32 search_id3_v2(UWORD8 *buffer) ++{ ++ UWORD32 temp; ++ ++ temp = buffer[0] << 16; ++ temp |= buffer[1] << 8; ++ temp |= buffer[2]; ++ ++ if (temp == ID3V2) ++ return 1; /* ID3 found */ ++ ++ return 0; /* ID3 not found */ ++} ++ ++/************************************************************** ++ * function name : search_id3_v1 ++ * ++ * description : finds if ID3V1 starts at the start of given buffer. ++ * ++ * arguments : input parameters ++ * buffer input buffer ++ * ++ * values returned : FLAG 1: ID3 found 0: ID3 not found ++ **************************************************************/ ++WORD32 search_id3_v1(UWORD8 *buffer) ++{ ++ UWORD32 temp; ++ ++ temp = buffer[0] << 16; ++ temp |= buffer[1] << 8; ++ temp |= buffer[2]; ++ ++ if (temp == ID3V1) ++ return 1; /* ID3 found */ ++ ++ return 0; /* ID3 not found */ ++} ++ ++/*************************************************************** ++ * function name : decode_id3_v1 ++ * ++ * description : decodes ID3V1 tag. ++ * ++ * arguments : input parameters ++ * buffer input buffer ++ * id3v1 structure ++ * ++ * values returned : bytes consumed ++ **************************************************************/ ++WORD32 decode_id3_v1(UWORD8 *buffer, id3v1_struct *id3v1) ++{ ++ WORD32 bytes_consumed = 0; ++ short tag_type; ++ ++ /* setting the tag type */ ++ tag_type = 1; ++ ++ bytes_consumed = get_v1_info(buffer, id3v1); ++ ++ return bytes_consumed; ++} ++ ++/*********************************************************** ++ * function name : get_v1_info ++ * ++ * description : gets ID3V1 information fields. ++ * ++ * arguments : input parameters ++ * buffer input buffer ++ * id3v1 structure ++ * ++ * values returned : bytes consumed ++ ***********************************************************/ ++WORD32 get_v1_info(UWORD8 *buffer, id3v1_struct *id3v1) ++{ ++ WORD32 i; ++ WORD32 bytes_consumed = 0; ++ ++ /* get song_title */ ++ for (i = 0; i < 30; i++) ++ id3v1->song_title[i] = buffer[i]; ++ ++ buffer += 30; ++ bytes_consumed += 30; ++ display1(id3v1->song_title, 30, (WORD8 *)"song_title : "); ++ ++ /* get artist */ ++ for (i = 0; i < 30; i++) ++ id3v1->artist[i] = buffer[i]; ++ ++ buffer += 30; ++ bytes_consumed += 30; ++ display1(id3v1->artist, 30, (WORD8 *)"artist : "); ++ ++ /* get album */ ++ for (i = 0; i < 30; i++) ++ id3v1->album[i] = buffer[i]; ++ ++ buffer += 30; ++ bytes_consumed += 30; ++ display1(id3v1->album, 30, (WORD8 *)"album : "); ++ ++ /* get year */ ++ for (i = 0; i < 4; i++) ++ id3v1->year[i] = buffer[i]; ++ ++ buffer += 4; ++ bytes_consumed += 4; ++ display1(id3v1->year, 4, (WORD8 *)"year : "); ++ ++ /* get comment */ ++ for (i = 0; i < 30; i++) ++ id3v1->comment[i] = buffer[i]; ++ ++ buffer += 30; ++ bytes_consumed += 30; ++ display1(id3v1->comment, 30, (WORD8 *)"comment : "); ++ ++ /* get genre */ ++ for (i = 0; i < 1; i++) ++ id3v1->genre[i] = buffer[i]; ++ ++ buffer += 1; ++ bytes_consumed += 1; ++ ++ return bytes_consumed; ++} ++ ++/***************************************************** ++ * function name : decode_id3_v2 ++ * ++ * description : decodes ID3V2 tag. ++ * ++ * arguments : input parameters ++ * buffer input buffer ++ * id3v2 structure ++ * continue_flag FLAG to indicate whether ++ * it is first call or not ++ * insize input buffer size ++ * ++ * values returned : bytes consumed ++ ******************************************************/ ++WORD32 decode_id3_v2(const char *const buffer, ++ id3v2_struct *const id3v2, ++ WORD32 continue_flag, ++ WORD32 insize) ++{ ++ UWORD32 size = 0, flag; ++ WORD32 i, buf_update_val; ++ UWORD8 buf[4], frame_header[10], id3_buffer[10]; ++ WORD8 *bitstream_ptr; ++ short tag_type; ++ ++ WORD32 bytes_consumed = 0; ++ ++ if (id3v2->header_end == 1) { ++ id3v2->bytes_consumed += insize; ++ if (id3v2->bytes_consumed < id3v2->id3_v2_header.size) ++ return 0; ++ ++ id3v2->bytes_consumed = (id3v2->id3_v2_header.size + 10); ++ return 1; ++ } ++ ++ bitstream_ptr = (WORD8 *)id3_buffer; ++ ++ if (!continue_flag) { ++ bytes_consumed += 3; ++ /* setting the tag type */ ++ tag_type = 2; ++ id3v2->id3_v2_header.version = buffer[bytes_consumed + 0] << 8; ++ id3v2->id3_v2_header.version |= buffer[bytes_consumed + 1]; ++ id3v2->id3_v2_header.flag = buffer[bytes_consumed + 2]; ++ ++ /* making the msb of each byte zero */ ++ buf[0] = buffer[bytes_consumed + 6] & 0x7f; ++ buf[1] = buffer[bytes_consumed + 5] & 0x7f; ++ buf[2] = buffer[bytes_consumed + 4] & 0x7f; ++ buf[3] = buffer[bytes_consumed + 3] & 0x7f; ++ ++ bytes_consumed += 7; ++ ++ /* concatenation the bytes after making ++ * 7th bit zero to get 28 bits size ++ */ ++ size = buf[0]; ++ size |= (buf[1] << 7); ++ size |= (buf[2] << 14); ++ size |= (buf[3] << 21); ++ /* storing the size */ ++ id3v2->id3_v2_header.size = size; ++ ++ /* check for extended header */ ++ if (id3v2->id3_v2_header.flag & 0x20) { ++ for (i = 0; i < 10; i++) ++ bitstream_ptr[i] = buffer[bytes_consumed + i]; ++ ++ i = 0; ++ bytes_consumed += 10; ++ ++ size = bitstream_ptr[i++] << 24; ++ size |= bitstream_ptr[i++] << 16; ++ size |= bitstream_ptr[i++] << 8; ++ size |= bitstream_ptr[i++]; ++ ++ /* two bytes for flag */ ++ i += 2; ++ { ++ UWORD32 padding_size; ++ ++ padding_size = bitstream_ptr[i++] << 24; ++ padding_size |= bitstream_ptr[i++] << 16; ++ padding_size |= bitstream_ptr[i++] << 8; ++ padding_size |= bitstream_ptr[i++]; ++ ++ /* skipping the padding and frame size ++ * number of bytes ++ */ ++ bytes_consumed += (padding_size + size); ++ } ++ } ++ } ++ ++ while (id3v2->header_end != 1) { ++ char *key; ++ id3_v2_frame_struct *value; ++ unsigned int avail_inp; ++ ++ /* reading the 10 bytes to get the frame header */ ++ ++ for (i = 0; i < 10; i++) ++ frame_header[i] = buffer[bytes_consumed + i]; ++ bytes_consumed += 10; ++ ++ /* getting the size from the header */ ++ size = frame_header[4] << 24; ++ size |= frame_header[5] << 16; ++ size |= frame_header[6] << 8; ++ size |= frame_header[7]; ++ ++ /* decoding the flag, currently not used */ ++ flag = frame_header[8] << 8; ++ flag |= frame_header[9]; ++ ++ avail_inp = insize - bytes_consumed; ++ ++ /* switching to the frame type */ ++ switch (CHAR4(frame_header[0], ++ frame_header[1], ++ frame_header[2], ++ frame_header[3])) { ++ case CHAR4('A', 'E', 'N', 'C'): ++ case CHAR4('A', 'P', 'I', 'C'): ++ case CHAR4('C', 'O', 'M', 'M'): ++ case CHAR4('C', 'O', 'M', 'R'): ++ case CHAR4('E', 'N', 'C', 'R'): ++ case CHAR4('E', 'Q', 'U', 'A'): ++ case CHAR4('E', 'T', 'C', 'O'): ++ case CHAR4('G', 'E', 'O', 'B'): ++ case CHAR4('G', 'R', 'I', 'D'): ++ case CHAR4('I', 'P', 'L', 'S'): ++ case CHAR4('L', 'I', 'N', 'K'): ++ case CHAR4('M', 'C', 'D', 'I'): ++ case CHAR4('M', 'L', 'L', 'T'): ++ case CHAR4('O', 'W', 'N', 'E'): ++ case CHAR4('P', 'C', 'N', 'T'): ++ case CHAR4('P', 'O', 'P', 'M'): ++ case CHAR4('P', 'O', 'S', 'S'): ++ case CHAR4('R', 'B', 'U', 'F'): ++ case CHAR4('R', 'V', 'A', 'D'): ++ case CHAR4('R', 'V', 'R', 'B'): ++ case CHAR4('S', 'Y', 'L', 'T'): ++ case CHAR4('S', 'Y', 'T', 'C'): ++ case CHAR4('T', 'B', 'P', 'M'): ++ case CHAR4('T', 'C', 'O', 'P'): ++ case CHAR4('T', 'D', 'A', 'T'): ++ case CHAR4('T', 'D', 'L', 'Y'): ++ case CHAR4('T', 'F', 'L', 'T'): ++ case CHAR4('T', 'I', 'M', 'E'): ++ case CHAR4('T', 'K', 'E', 'Y'): ++ case CHAR4('T', 'L', 'A', 'N'): ++ case CHAR4('T', 'L', 'E', 'N'): ++ case CHAR4('T', 'M', 'E', 'D'): ++ case CHAR4('T', 'O', 'F', 'N'): ++ case CHAR4('T', 'O', 'L', 'Y'): ++ case CHAR4('T', 'O', 'R', 'Y'): ++ case CHAR4('T', 'P', 'E', '2'): ++ case CHAR4('T', 'P', 'E', '3'): ++ case CHAR4('T', 'P', 'E', '4'): ++ case CHAR4('T', 'P', 'O', 'S'): ++ case CHAR4('T', 'R', 'C', 'K'): ++ case CHAR4('T', 'R', 'D', 'A'): ++ case CHAR4('T', 'R', 'S', 'N'): ++ case CHAR4('T', 'R', 'S', 'O'): ++ case CHAR4('T', 'S', 'I', 'Z'): ++ case CHAR4('T', 'S', 'R', 'C'): ++ case CHAR4('T', 'S', 'S', 'E'): ++ case CHAR4('T', 'Y', 'E', 'R'): ++ case CHAR4('T', 'X', 'X', 'X'): ++ case CHAR4('U', 'F', 'I', 'D'): ++ case CHAR4('U', 'S', 'E', 'R'): ++ case CHAR4('U', 'S', 'L', 'T'): ++ case CHAR4('W', 'C', 'O', 'M'): ++ case CHAR4('W', 'C', 'O', 'P'): ++ case CHAR4('W', 'O', 'A', 'F'): ++ case CHAR4('W', 'O', 'A', 'R'): ++ case CHAR4('W', 'O', 'A', 'S'): ++ case CHAR4('W', 'O', 'R', 'S'): ++ case CHAR4('W', 'P', 'A', 'Y'): ++ case CHAR4('W', 'P', 'U', 'B'): ++ case CHAR4('W', 'X', 'X', 'X'): ++ case CHAR4('T', 'I', 'T', '3'): ++ key = "other_info : "; ++ value = &id3v2->other_info; ++ break; ++ case CHAR4('P', 'R', 'I', 'V'): ++ key = "private_frame : "; ++ value = &id3v2->private_frame; ++ break; ++ case CHAR4('T', 'A', 'L', 'B'): ++ key = "album_movie_show_title : "; ++ value = &id3v2->album_movie_show_title; ++ break; ++ case CHAR4('T', 'C', 'O', 'M'): ++ key = "composer_name : "; ++ value = &id3v2->composer_name; ++ break; ++ case CHAR4('T', 'C', 'O', 'N'): ++ key = "content_type : "; ++ value = &id3v2->content_type; ++ break; ++ case CHAR4('T', 'E', 'N', 'C'): ++ key = "encoded_by : "; ++ value = &id3v2->encoded_by; ++ break; ++ case CHAR4('T', 'E', 'X', 'T'): ++ key = "lyricist_text_writer : "; ++ value = &id3v2->lyricist_text_writer; ++ break; ++ case CHAR4('T', 'I', 'T', '1'): ++ key = "content_group_description : "; ++ value = &id3v2->content_group_description; ++ break; ++ case CHAR4('T', 'I', 'T', '2'): ++ key = "title_songname_content_description : "; ++ value = &id3v2->title_songname_content_description; ++ break; ++ case CHAR4('T', 'O', 'A', 'L'): ++ key = "original_album_movie_show_title : "; ++ value = &id3v2->original_album_movie_show_title; ++ break; ++ case CHAR4('T', 'O', 'P', 'E'): ++ key = "original_artist_performer : "; ++ value = &id3v2->original_artist_performer; ++ break; ++ case CHAR4('T', 'O', 'W', 'N'): ++ key = "file_owner_licensee : "; ++ value = &id3v2->file_owner_licensee; ++ break; ++ case CHAR4('T', 'P', 'E', '1'): ++ key = "lead_performer_soloist : "; ++ value = &id3v2->lead_performer_soloist; ++ break; ++ case CHAR4('T', 'P', 'U', 'B'): ++ key = "publisher : "; ++ value = &id3v2->publisher; ++ break; ++ default: ++ /* skipping the read 10 bytes */ ++ buf_update_val = -10; ++ id3v2->header_end = 1; ++ value = 0; ++ key = 0; ++ break; ++ } ++ ++ if (value != 0) ++ buf_update_val = get_info(&buffer[bytes_consumed], ++ avail_inp, size, value); ++ ++ /* Negative value for buf_update_val means one of two things: ++ * 1. The default case happened and we're done with ID3V2 tag ++ * frames, or ++ * 2. get_info() returned -1 to indicate that more input is ++ * required to decode this frame of the tag. ++ */ ++ if (buf_update_val >= 0) ++ display2(value, ++ umin(value->max_size, buf_update_val), key); ++ ++ if (buf_update_val == -1) { ++ id3v2->bytes_consumed += bytes_consumed; ++ return 1; ++ } ++ ++ bytes_consumed += buf_update_val; ++ ++ /* Is there enough input left (10 bytes) to begin ++ * decoding another frame? If not, bag out temporarily ++ * now. The caller will refill our input buffer and ++ * call us again with continue_flag == 1. ++ */ ++ if (insize - bytes_consumed < 10) { ++ id3v2->bytes_consumed += bytes_consumed; ++ return 0; /* not completely decoded */ ++ } ++ } ++ ++ id3v2->bytes_consumed += bytes_consumed; ++ if ((id3v2->bytes_consumed + 10) < id3v2->id3_v2_header.size) ++ return 0; /* not completely decoded */ ++ ++ return 1; /* completely decoded */ ++} ++ ++/******************************************************* ++ * function name : get_id3_v2_bytes ++ * ++ * description : tells the size of ID3V2 tag. ++ * ++ * arguments : input parameters ++ * buffer input buffer ++ * ++ * values returned : bytes consumed ++ ********************************************************/ ++WORD32 get_id3_v2_bytes(UWORD8 *buffer) ++{ ++ WORD32 size; ++ ++ /* making the msb of each byte zero */ ++ size = (buffer[9] & 0x7f); ++ size |= ((buffer[8] & 0x7f) << 7); ++ size |= ((buffer[7] & 0x7f) << 14); ++ size |= ((buffer[6] & 0x7f) << 21); ++ ++ return (size + 10); ++} ++ ++/**************************************************** ++ * function name : get_info ++ * ++ * description : read the frame information from the input buffer. ++ * ++ * arguments : input parameters ++ * ++ * values returned : update value for buffer ++ ****************************************************/ ++WORD32 get_info(const char *inp_buffer, ++ unsigned int avail_inp, ++ WORD32 tag_size, ++ id3_v2_frame_struct *dest) ++{ ++ WORD32 j; ++ ++ /* setting the tag to indicate the presence of frame */ ++ dest->tag_present = 1; ++ /* If there isn't enough input available, we punt back to the top ++ * level and ask for more. ++ */ ++ if (avail_inp < umin(tag_size, dest->max_size)) ++ return -1; ++ ++ if (dest->max_size >= tag_size) { ++ for (j = 0; j < tag_size ; j++) ++ dest->frame_data[j] = inp_buffer[j]; ++ } else { ++ dest->exceeds_buffer_size = 1; ++ for (j = 0; j < dest->max_size ; j++) ++ dest->frame_data[j] = inp_buffer[j]; ++ } ++ return tag_size; ++} +-- +2.7.4 + diff --git a/recipes-multimedia/tinycompress/tinycompress_1.1.6.bb b/recipes-multimedia/tinycompress/tinycompress_1.1.6.bb new file mode 100644 index 0000000..d38f749 --- /dev/null +++ b/recipes-multimedia/tinycompress/tinycompress_1.1.6.bb @@ -0,0 +1,13 @@ +SUMMARY = "tinycompress library for compress audio offload in alsa" +DESCRIPTION = "A library to handle compressed formats like MP3 etc" +LICENSE = "BSD-3-clause" + +inherit autotools pkgconfig +LIC_FILES_CHKSUM = "file://COPYING;md5=cf9105c1a2d4405cbe04bbe3367373a0" + +SRC_URI = "git://git.alsa-project.org/tinycompress.git;protocol=git;branch=master \ + file://0001-tinycompress-Add-id3-decoding.patch \ +" +SRCREV = "995f2ed91045dad8c20485ab1a64727d22cd92e5" + +S = "${WORKDIR}/git" -- cgit v1.2.3