mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-11-09 21:22:39 -05:00
Realmedia related codecs fixes and enhancements
* More tolerance to the file format variations. * AC3 coded files in realaudio format are now playable Full credit to Igor Poretsky Change-Id: Id24e94bc00623e89fb8c80403efa92f69ab1e5d7
This commit is contained in:
parent
eee3f0ce79
commit
9b9b30bd54
8 changed files with 309 additions and 124 deletions
|
|
@ -27,8 +27,6 @@
|
|||
#include "codeclib.h"
|
||||
#endif
|
||||
|
||||
#define SWAP(a, b) do{uint8_t SWAP_tmp= b; b= a; a= SWAP_tmp;}while(0)
|
||||
|
||||
#ifdef TEST
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
|
@ -500,17 +498,33 @@ void rm_get_packet_fd(int fd,RMContext *rmctx, RMPacket *pkt)
|
|||
}
|
||||
#endif /*TEST*/
|
||||
|
||||
void rm_ac3_swap_bytes(uint8_t *buf, int bufsize)
|
||||
{
|
||||
uint8_t *bufptr;
|
||||
for (bufptr = buf; bufptr < buf + bufsize - 1; bufptr += 2)
|
||||
{
|
||||
bufptr[0] ^= bufptr[1];
|
||||
bufptr[1] ^= bufptr[0];
|
||||
bufptr[0] ^= bufptr[1];
|
||||
}
|
||||
}
|
||||
|
||||
int rm_get_packet(uint8_t **src,RMContext *rmctx, RMPacket *pkt)
|
||||
{
|
||||
int consumed = 0;
|
||||
int headerlen;
|
||||
/* rockbox: comment 'set but unused' variables
|
||||
uint8_t unknown;
|
||||
*/
|
||||
uint16_t x, place;
|
||||
uint16_t x;
|
||||
uint16_t sps = rmctx->sub_packet_size;
|
||||
uint16_t h = rmctx->sub_packet_h;
|
||||
uint16_t y = rmctx->sub_packet_cnt;
|
||||
uint16_t y = 0;
|
||||
uint16_t w = rmctx->audio_framesize;
|
||||
|
||||
rmctx->sub_packet_cnt = 0;
|
||||
rmctx->audio_pkt_cnt = 0;
|
||||
|
||||
do
|
||||
{
|
||||
y = rmctx->sub_packet_cnt;
|
||||
|
|
@ -523,6 +537,7 @@ int rm_get_packet(uint8_t **src,RMContext *rmctx, RMPacket *pkt)
|
|||
return -1;
|
||||
}
|
||||
|
||||
headerlen = PACKET_HEADER_SIZE + (pkt->version ? 1 : 0);
|
||||
pkt->length = rm_get_uint16be(*src+2);
|
||||
pkt->stream_number = rm_get_uint16be(*src+4);
|
||||
pkt->timestamp = rm_get_uint32be(*src+6);
|
||||
|
|
@ -534,25 +549,27 @@ int rm_get_packet(uint8_t **src,RMContext *rmctx, RMPacket *pkt)
|
|||
pkt->flags = rm_get_uint8(*src+11);
|
||||
|
||||
if(pkt->version == 1)
|
||||
/* unknown = */ rm_get_uint8(*src+10);
|
||||
/* unknown = */ rm_get_uint8(*src+12);
|
||||
|
||||
if (pkt->flags & 2) /* keyframe */
|
||||
y = rmctx->sub_packet_cnt = 0;
|
||||
if (pkt->flags & 2) { /* keyframe */
|
||||
if (y)
|
||||
return consumed;
|
||||
y = 0;
|
||||
}
|
||||
if (!y)
|
||||
rmctx->audiotimestamp = pkt->timestamp;
|
||||
|
||||
|
||||
/* Skip packet header */
|
||||
advance_buffer(src, PACKET_HEADER_SIZE);
|
||||
consumed += PACKET_HEADER_SIZE;
|
||||
advance_buffer(src, headerlen);
|
||||
consumed += headerlen;
|
||||
if (rmctx->codec_type == CODEC_COOK || rmctx->codec_type == CODEC_ATRAC) {
|
||||
for(x = 0 ; x < w/sps; x++)
|
||||
{
|
||||
place = sps*(h*x+((h+1)/2)*(y&1)+(y>>1));
|
||||
pkt->frames[place/sps] = *src;
|
||||
pkt->frames[h*x+((h+1)/2)*(y&1)+(y>>1)] = *src;
|
||||
advance_buffer(src,sps);
|
||||
consumed += sps;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (rmctx->codec_type == CODEC_AAC) {
|
||||
rmctx->sub_packet_cnt = (rm_get_uint16be(*src) & 0xf0) >> 4;
|
||||
advance_buffer(src, 2);
|
||||
|
|
@ -563,22 +580,22 @@ int rm_get_packet(uint8_t **src,RMContext *rmctx, RMPacket *pkt)
|
|||
advance_buffer(src, 2);
|
||||
consumed += 2;
|
||||
}
|
||||
rmctx->audio_pkt_cnt = --rmctx->sub_packet_cnt;
|
||||
rmctx->audio_pkt_cnt = rmctx->sub_packet_cnt;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
else if (rmctx->codec_type == CODEC_AC3) {
|
||||
/* The byte order of the data is reversed from standard AC3 */
|
||||
for(x = 0; x < pkt->length - PACKET_HEADER_SIZE; x+=2) {
|
||||
SWAP((*src)[0], (*src)[1]);
|
||||
*src += 2;
|
||||
}
|
||||
*src -= x;
|
||||
rm_ac3_swap_bytes(*src, pkt->length - headerlen);
|
||||
break;
|
||||
}
|
||||
else return -1; /* invalid codec type */
|
||||
|
||||
rmctx->audio_pkt_cnt++;
|
||||
}while(++(rmctx->sub_packet_cnt) < h);
|
||||
|
||||
return consumed;
|
||||
return consumed;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
|
@ -587,6 +604,6 @@ void dump_rm_context(RMContext *rmctx)
|
|||
DEBUGF("block_align = %d\n", rmctx->block_align);
|
||||
DEBUGF("nb_channels = %d\n", rmctx->nb_channels);
|
||||
DEBUGF("sample_rate = %d\n", rmctx->sample_rate);
|
||||
DEBUGF("bit_rate = %d\n", rmctx->bit_rate );
|
||||
DEBUGF("bit_rate = %ld\n", rmctx->bit_rate );
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -25,6 +25,9 @@
|
|||
#include <inttypes.h>
|
||||
#include "bytestream.h"
|
||||
|
||||
#define RM_RAW_DATASTREAM 0x0100
|
||||
#define RM_PKT_V1 0x0200
|
||||
|
||||
#define MAX_EXTRADATA_SIZE 16
|
||||
#define DATA_HEADER_SIZE 18
|
||||
#define PACKET_HEADER_SIZE 12
|
||||
|
|
@ -86,6 +89,8 @@ typedef struct rm_context
|
|||
|
||||
int real_parse_header(int fd, RMContext *rmctx);
|
||||
|
||||
void rm_ac3_swap_bytes(uint8_t *buf, int bufsize);
|
||||
|
||||
/* Get a (sub_packet_h*frames_per_packet) number of audio frames from a memory buffer */
|
||||
int rm_get_packet(uint8_t **src,RMContext *rmctx, RMPacket *pkt);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue