forked from len0rd/rockbox
"Detach" ATRAC3 from RM. Since ATRAC3 isn't really specific to RM, it must not be obligatory to initialize the decoder through RMContext.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@24682 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
419e8aad78
commit
2e314093c8
6 changed files with 45 additions and 54 deletions
|
|
@ -31,24 +31,8 @@ CODEC_HEADER
|
||||||
#define FRAMESIZE ci->id3->bytesperframe
|
#define FRAMESIZE ci->id3->bytesperframe
|
||||||
#define BITRATE ci->id3->bitrate
|
#define BITRATE ci->id3->bitrate
|
||||||
|
|
||||||
/* The codec has nothing to do with RM, it just uses an RMContext struct to *
|
|
||||||
* store the data needs to be passed to the decoder initializing function. */
|
|
||||||
RMContext rmctx;
|
|
||||||
ATRAC3Context q IBSS_ATTR;
|
ATRAC3Context q IBSS_ATTR;
|
||||||
|
|
||||||
static void init_rm(RMContext *rmctx, struct mp3entry *id3)
|
|
||||||
{
|
|
||||||
rmctx->sample_rate = id3->frequency;
|
|
||||||
rmctx->nb_channels = 2;
|
|
||||||
rmctx->bit_rate = id3->bitrate;
|
|
||||||
rmctx->block_align = id3->bytesperframe;
|
|
||||||
|
|
||||||
/* 14-byte extra-data was faked in the metadata parser so that *
|
|
||||||
* the ATRAC3 decoder would parse it as WAV format extra-data. */
|
|
||||||
rmctx->extradata_size = 14;
|
|
||||||
memcpy(rmctx->codec_extradata, &id3->id3v1buf[0][0], 14);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* this is the codec entry point */
|
/* this is the codec entry point */
|
||||||
enum codec_status codec_main(void)
|
enum codec_status codec_main(void)
|
||||||
{
|
{
|
||||||
|
|
@ -67,17 +51,14 @@ next_track:
|
||||||
ci->sleep(1);
|
ci->sleep(1);
|
||||||
|
|
||||||
codec_set_replaygain(ci->id3);
|
codec_set_replaygain(ci->id3);
|
||||||
ci->memset(&rmctx,0,sizeof(RMContext));
|
|
||||||
ci->memset(&q,0,sizeof(ATRAC3Context));
|
ci->memset(&q,0,sizeof(ATRAC3Context));
|
||||||
|
|
||||||
init_rm(&rmctx, ci->id3);
|
|
||||||
|
|
||||||
ci->configure(DSP_SET_FREQUENCY, ci->id3->frequency);
|
ci->configure(DSP_SET_FREQUENCY, ci->id3->frequency);
|
||||||
ci->configure(DSP_SET_SAMPLE_DEPTH, 17); /* Remark: atrac3 uses s15.0 by default, s15.2 was hacked. */
|
ci->configure(DSP_SET_SAMPLE_DEPTH, 17); /* Remark: atrac3 uses s15.0 by default, s15.2 was hacked. */
|
||||||
ci->configure(DSP_SET_STEREO_MODE, rmctx.nb_channels == 1 ?
|
ci->configure(DSP_SET_STEREO_MODE, ci->id3->channels == 1 ?
|
||||||
STEREO_MONO : STEREO_NONINTERLEAVED);
|
STEREO_MONO : STEREO_NONINTERLEAVED);
|
||||||
|
|
||||||
res =atrac3_decode_init(&q, &rmctx);
|
res =atrac3_decode_init(&q, ci->id3);
|
||||||
if(res < 0) {
|
if(res < 0) {
|
||||||
DEBUGF("failed to initialize atrac decoder\n");
|
DEBUGF("failed to initialize atrac decoder\n");
|
||||||
return CODEC_ERROR;
|
return CODEC_ERROR;
|
||||||
|
|
@ -133,7 +114,7 @@ seek_start :
|
||||||
ci->seek_complete();
|
ci->seek_complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
res = atrac3_decode_frame(&rmctx, &q, &datasize, bit_buffer, FRAMESIZE);
|
res = atrac3_decode_frame(FRAMESIZE, &q, &datasize, bit_buffer, FRAMESIZE);
|
||||||
|
|
||||||
if(res != (int)FRAMESIZE) {
|
if(res != (int)FRAMESIZE) {
|
||||||
DEBUGF("codec error\n");
|
DEBUGF("codec error\n");
|
||||||
|
|
@ -141,7 +122,7 @@ seek_start :
|
||||||
}
|
}
|
||||||
|
|
||||||
if(datasize)
|
if(datasize)
|
||||||
ci->pcmbuf_insert(q.outSamples, q.outSamples + 1024, q.samples_per_frame / rmctx.nb_channels);
|
ci->pcmbuf_insert(q.outSamples, q.outSamples + 1024, q.samples_per_frame / ci->id3->channels);
|
||||||
|
|
||||||
elapsed += (FRAMESIZE * 8) / BITRATE;
|
elapsed += (FRAMESIZE * 8) / BITRATE;
|
||||||
ci->set_elapsed(elapsed);
|
ci->set_elapsed(elapsed);
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,11 @@ ATRAC3Context q IBSS_ATTR;
|
||||||
|
|
||||||
static void init_rm(RMContext *rmctx)
|
static void init_rm(RMContext *rmctx)
|
||||||
{
|
{
|
||||||
|
/* initialize the RMContext */
|
||||||
memcpy(rmctx, (void*)(( (intptr_t)ci->id3->id3v2buf + 3 ) &~ 3), sizeof(RMContext));
|
memcpy(rmctx, (void*)(( (intptr_t)ci->id3->id3v2buf + 3 ) &~ 3), sizeof(RMContext));
|
||||||
|
|
||||||
|
/* and atrac3 expects extadata in id3v2buf, so we shall give it that */
|
||||||
|
memcpy(ci->id3->id3v2buf, (char*)rmctx->codec_extradata, rmctx->extradata_size*sizeof(char));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* this is the codec entry point */
|
/* this is the codec entry point */
|
||||||
|
|
@ -77,7 +81,7 @@ next_track:
|
||||||
h = rmctx.sub_packet_h;
|
h = rmctx.sub_packet_h;
|
||||||
scrambling_unit_size = h*fs;
|
scrambling_unit_size = h*fs;
|
||||||
|
|
||||||
res =atrac3_decode_init(&q, &rmctx);
|
res =atrac3_decode_init(&q, ci->id3);
|
||||||
if(res < 0) {
|
if(res < 0) {
|
||||||
DEBUGF("failed to initialize atrac decoder\n");
|
DEBUGF("failed to initialize atrac decoder\n");
|
||||||
return CODEC_ERROR;
|
return CODEC_ERROR;
|
||||||
|
|
@ -168,7 +172,7 @@ seek_start :
|
||||||
ci->seek_complete();
|
ci->seek_complete();
|
||||||
}
|
}
|
||||||
if(pkt.length)
|
if(pkt.length)
|
||||||
res = atrac3_decode_frame(&rmctx, &q, &datasize, pkt.frames[i], rmctx.block_align);
|
res = atrac3_decode_frame(rmctx.block_align, &q, &datasize, pkt.frames[i], rmctx.block_align);
|
||||||
else /* indicates that there are no remaining frames */
|
else /* indicates that there are no remaining frames */
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1074,17 +1074,17 @@ static int decodeFrame(ATRAC3Context *q, const uint8_t* databuf, int off)
|
||||||
* @param rmctx pointer to the AVCodecContext
|
* @param rmctx pointer to the AVCodecContext
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int atrac3_decode_frame(RMContext *rmctx, ATRAC3Context *q,
|
int atrac3_decode_frame(unsigned long block_align, ATRAC3Context *q,
|
||||||
int *data_size, const uint8_t *buf, int buf_size) {
|
int *data_size, const uint8_t *buf, int buf_size) {
|
||||||
int result = 0, off = 0;
|
int result = 0, off = 0;
|
||||||
const uint8_t* databuf;
|
const uint8_t* databuf;
|
||||||
|
|
||||||
if (buf_size < rmctx->block_align)
|
if (buf_size < block_align)
|
||||||
return buf_size;
|
return buf_size;
|
||||||
|
|
||||||
/* Check if we need to descramble and what buffer to pass on. */
|
/* Check if we need to descramble and what buffer to pass on. */
|
||||||
if (q->scrambled_stream) {
|
if (q->scrambled_stream) {
|
||||||
off = decode_bytes(buf, q->decoded_bytes_buffer, rmctx->block_align);
|
off = decode_bytes(buf, q->decoded_bytes_buffer, block_align);
|
||||||
databuf = q->decoded_bytes_buffer;
|
databuf = q->decoded_bytes_buffer;
|
||||||
} else {
|
} else {
|
||||||
databuf = buf;
|
databuf = buf;
|
||||||
|
|
@ -1102,7 +1102,7 @@ int atrac3_decode_frame(RMContext *rmctx, ATRAC3Context *q,
|
||||||
else
|
else
|
||||||
*data_size = 2048 * sizeof(int32_t);
|
*data_size = 2048 * sizeof(int32_t);
|
||||||
|
|
||||||
return rmctx->block_align;
|
return block_align;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1111,23 +1111,23 @@ int atrac3_decode_frame(RMContext *rmctx, ATRAC3Context *q,
|
||||||
*
|
*
|
||||||
* @param rmctx pointer to the RMContext
|
* @param rmctx pointer to the RMContext
|
||||||
*/
|
*/
|
||||||
|
int atrac3_decode_init(ATRAC3Context *q, struct mp3entry *id3)
|
||||||
int atrac3_decode_init(ATRAC3Context *q, RMContext *rmctx)
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
uint8_t *edata_ptr = rmctx->codec_extradata;
|
uint8_t *edata_ptr = (uint8_t*)&id3->id3v2buf;
|
||||||
static VLC_TYPE atrac3_vlc_table[4096][2];
|
static VLC_TYPE atrac3_vlc_table[4096][2];
|
||||||
static int vlcs_initialized = 0;
|
static int vlcs_initialized = 0;
|
||||||
|
|
||||||
/* Take data from the AVCodecContext (RM container). */
|
/* Take data from the RM container. */
|
||||||
q->sample_rate = rmctx->sample_rate;
|
q->sample_rate = id3->frequency;
|
||||||
q->channels = rmctx->nb_channels;
|
q->channels = id3->channels;
|
||||||
q->bit_rate = rmctx->bit_rate;
|
q->bit_rate = id3->bitrate * 1000;
|
||||||
q->bits_per_frame = rmctx->block_align * 8;
|
q->bits_per_frame = id3->bytesperframe * 8;
|
||||||
q->bytes_per_frame = rmctx->block_align;
|
q->bytes_per_frame = id3->bytesperframe;
|
||||||
|
|
||||||
/* Take care of the codec-specific extradata. */
|
/* Take care of the codec-specific extradata. */
|
||||||
if (rmctx->extradata_size == 14) {
|
|
||||||
|
if (id3->extradata_size == 14) {
|
||||||
/* Parse the extradata, WAV format */
|
/* Parse the extradata, WAV format */
|
||||||
DEBUGF("[0-1] %d\n",rm_get_uint16le(&edata_ptr[0])); /* Unknown value always 1 */
|
DEBUGF("[0-1] %d\n",rm_get_uint16le(&edata_ptr[0])); /* Unknown value always 1 */
|
||||||
q->samples_per_channel = rm_get_uint32le(&edata_ptr[2]);
|
q->samples_per_channel = rm_get_uint32le(&edata_ptr[2]);
|
||||||
|
|
@ -1152,7 +1152,7 @@ int atrac3_decode_init(ATRAC3Context *q, RMContext *rmctx)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (rmctx->extradata_size == 10) {
|
} else if (id3->extradata_size == 10) {
|
||||||
/* Parse the extradata, RM format. */
|
/* Parse the extradata, RM format. */
|
||||||
q->atrac3version = rm_get_uint32be(&edata_ptr[0]);
|
q->atrac3version = rm_get_uint32be(&edata_ptr[0]);
|
||||||
q->samples_per_frame = rm_get_uint16be(&edata_ptr[4]);
|
q->samples_per_frame = rm_get_uint16be(&edata_ptr[4]);
|
||||||
|
|
@ -1163,7 +1163,7 @@ int atrac3_decode_init(ATRAC3Context *q, RMContext *rmctx)
|
||||||
q->scrambled_stream = 1;
|
q->scrambled_stream = 1;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
DEBUGF("Unknown extradata size %d.\n",rmctx->extradata_size);
|
DEBUGF("Unknown extradata size %d.\n",id3->extradata_size);
|
||||||
}
|
}
|
||||||
/* Check the extradata. */
|
/* Check the extradata. */
|
||||||
|
|
||||||
|
|
@ -1191,13 +1191,13 @@ int atrac3_decode_init(ATRAC3Context *q, RMContext *rmctx)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rmctx->nb_channels <= 0 || rmctx->nb_channels > 2 /*|| ((rmctx->channels * 1024) != q->samples_per_frame)*/) {
|
if (id3->channels <= 0 || id3->channels > 2 ) {
|
||||||
DEBUGF("Channel configuration error!\n");
|
DEBUGF("Channel configuration error!\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if(rmctx->block_align >= UINT16_MAX/2)
|
if(id3->bytesperframe >= UINT16_MAX/2)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
#include "ffmpeg_bitstream.h"
|
#include "ffmpeg_bitstream.h"
|
||||||
#include "../librm/rm.h"
|
#include "../librm/rm.h"
|
||||||
|
#ifdef ROCKBOX
|
||||||
|
#include "codeclib.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if (CONFIG_CPU == PP5022) || (CONFIG_CPU == PP5024) || (CONFIG_CPU == MCF5250)
|
#if (CONFIG_CPU == PP5022) || (CONFIG_CPU == PP5024) || (CONFIG_CPU == MCF5250)
|
||||||
/* PP5022/24 and MCF5250 have larger IRAM */
|
/* PP5022/24 and MCF5250 have larger IRAM */
|
||||||
|
|
@ -82,8 +85,8 @@ typedef struct {
|
||||||
//@}
|
//@}
|
||||||
} ATRAC3Context;
|
} ATRAC3Context;
|
||||||
|
|
||||||
int atrac3_decode_init(ATRAC3Context *q, RMContext *rmctx);
|
int atrac3_decode_init(ATRAC3Context *q, struct mp3entry *id3);
|
||||||
|
|
||||||
int atrac3_decode_frame(RMContext *rmctx, ATRAC3Context *q,
|
int atrac3_decode_frame(unsigned long block_align, ATRAC3Context *q,
|
||||||
int *data_size, const uint8_t *buf, int buf_size);
|
int *data_size, const uint8_t *buf, int buf_size);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -137,7 +137,7 @@ int oma_read_header(int fd, struct mp3entry* id3)
|
||||||
case OMA_CODECID_ATRAC3:
|
case OMA_CODECID_ATRAC3:
|
||||||
id3->frequency = srate_tab[(codec_params >> 13) & 7]*100;
|
id3->frequency = srate_tab[(codec_params >> 13) & 7]*100;
|
||||||
if (id3->frequency != 44100) {
|
if (id3->frequency != 44100) {
|
||||||
DEBUGF("Unsupported sample rate, send sample file to developers: %d\n", samplerate);
|
DEBUGF("Unsupported sample rate, send sample file to developers: %d\n", id3->frequency);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -149,16 +149,17 @@ int oma_read_header(int fd, struct mp3entry* id3)
|
||||||
|
|
||||||
/* fake the atrac3 extradata (wav format, makes stream copy to wav work) */
|
/* fake the atrac3 extradata (wav format, makes stream copy to wav work) */
|
||||||
/* ATRAC3 expects and extra-data size of 14 bytes for wav format; extra-data size *
|
/* ATRAC3 expects and extra-data size of 14 bytes for wav format; extra-data size *
|
||||||
* is stored in ATRAC3Context before initializing the decoder. See atrac3_oma.codec. *
|
* is stored in ATRAC3Context before initializing the decoder. *
|
||||||
* We use id3v2buf to hold the (fake) extra-data provided from the container. */
|
* We use id3v2buf to hold the (fake) extra-data provided from the container. */
|
||||||
|
id3->extradata_size = 14;
|
||||||
|
AV_WL16(&id3->id3v2buf[0], 1); // always 1
|
||||||
|
AV_WL32(&id3->id3v2buf[2], id3->frequency); // samples rate
|
||||||
|
AV_WL16(&id3->id3v2buf[6], jsflag); // coding mode
|
||||||
|
AV_WL16(&id3->id3v2buf[8], jsflag); // coding mode
|
||||||
|
AV_WL16(&id3->id3v2buf[10], 1); // always 1
|
||||||
|
AV_WL16(&id3->id3v2buf[12], 0); // always 0
|
||||||
|
|
||||||
AV_WL16(&id3->id3v1buf[0][0], 1); // always 1
|
id3->channels = 2;
|
||||||
AV_WL32(&id3->id3v1buf[0][2], id3->frequency); // samples rate
|
|
||||||
AV_WL16(&id3->id3v1buf[0][6], jsflag); // coding mode
|
|
||||||
AV_WL16(&id3->id3v1buf[0][8], jsflag); // coding mode
|
|
||||||
AV_WL16(&id3->id3v1buf[0][10], 1); // always 1
|
|
||||||
AV_WL16(&id3->id3v1buf[0][12], 0); // always 0
|
|
||||||
|
|
||||||
DEBUGF("sample_rate = %d\n", id3->frequency);
|
DEBUGF("sample_rate = %d\n", id3->frequency);
|
||||||
DEBUGF("frame_size = %d\n", id3->bytesperframe);
|
DEBUGF("frame_size = %d\n", id3->bytesperframe);
|
||||||
DEBUGF("stereo_coding_mode = %d\n", jsflag);
|
DEBUGF("stereo_coding_mode = %d\n", jsflag);
|
||||||
|
|
|
||||||
|
|
@ -438,6 +438,8 @@ bool get_rm_metadata(int fd, struct mp3entry* id3)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
id3->channels = rmctx->nb_channels;
|
||||||
|
id3->extradata_size = rmctx->extradata_size;
|
||||||
id3->bitrate = rmctx->bit_rate / 1000;
|
id3->bitrate = rmctx->bit_rate / 1000;
|
||||||
id3->frequency = rmctx->sample_rate;
|
id3->frequency = rmctx->sample_rate;
|
||||||
id3->length = rmctx->duration;
|
id3->length = rmctx->duration;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue