Commit e0f7e329 authored by Benjamin Larsson's avatar Benjamin Larsson Committed by Roberto Togni

Cook compatibe decoder, patch by Benjamin Larsson

Add cook demucing, change rm demuxer so that it reorders audio packets
before sending them to the decoder, and send minimum decodeable sized
packets; pass only real codec extradata fo the decoder
Fix 28_8 decoder for the new demuxer strategy

Originally committed as revision 4726 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent 60d76256
...@@ -32,6 +32,9 @@ endif ...@@ -32,6 +32,9 @@ endif
ifeq ($(CONFIG_CINEPAK_DECODER),yes) ifeq ($(CONFIG_CINEPAK_DECODER),yes)
OBJS+= cinepak.o OBJS+= cinepak.o
endif endif
ifeq ($(CONFIG_COOK_DECODER),yes)
OBJS+= cook.o
endif
ifneq ($(CONFIG_CLJR_DECODER)$(CONFIG_CLJR_ENCODER),) ifneq ($(CONFIG_CLJR_DECODER)$(CONFIG_CLJR_ENCODER),)
OBJS+= cljr.o OBJS+= cljr.o
endif endif
......
...@@ -491,6 +491,9 @@ void avcodec_register_all(void) ...@@ -491,6 +491,9 @@ void avcodec_register_all(void)
#ifdef CONFIG_QDM2_DECODER #ifdef CONFIG_QDM2_DECODER
register_avcodec(&qdm2_decoder); register_avcodec(&qdm2_decoder);
#endif //CONFIG_QDM2_DECODER #endif //CONFIG_QDM2_DECODER
#ifdef CONFIG_COOK_DECODER
register_avcodec(&cook_decoder);
#endif //CONFIG_COOK_DECODER
#ifdef CONFIG_RAWVIDEO_DECODER #ifdef CONFIG_RAWVIDEO_DECODER
register_avcodec(&rawvideo_decoder); register_avcodec(&rawvideo_decoder);
#endif //CONFIG_RAWVIDEO_DECODER #endif //CONFIG_RAWVIDEO_DECODER
......
...@@ -21,8 +21,8 @@ extern "C" { ...@@ -21,8 +21,8 @@ extern "C" {
#define AV_STRINGIFY(s) AV_TOSTRING(s) #define AV_STRINGIFY(s) AV_TOSTRING(s)
#define AV_TOSTRING(s) #s #define AV_TOSTRING(s) #s
#define LIBAVCODEC_VERSION_INT ((50<<16)+(1<<8)+0) #define LIBAVCODEC_VERSION_INT ((51<<16)+(0<<8)+0)
#define LIBAVCODEC_VERSION 50.1.0 #define LIBAVCODEC_VERSION 51.0.0
#define LIBAVCODEC_BUILD LIBAVCODEC_VERSION_INT #define LIBAVCODEC_BUILD LIBAVCODEC_VERSION_INT
#define LIBAVCODEC_IDENT "Lavc" AV_STRINGIFY(LIBAVCODEC_VERSION) #define LIBAVCODEC_IDENT "Lavc" AV_STRINGIFY(LIBAVCODEC_VERSION)
...@@ -187,6 +187,7 @@ enum CodecID { ...@@ -187,6 +187,7 @@ enum CodecID {
CODEC_ID_WESTWOOD_SND1, CODEC_ID_WESTWOOD_SND1,
CODEC_ID_GSM, CODEC_ID_GSM,
CODEC_ID_QDM2, CODEC_ID_QDM2,
CODEC_ID_COOK,
CODEC_ID_OGGTHEORA= 0x16000, CODEC_ID_OGGTHEORA= 0x16000,
...@@ -2004,6 +2005,7 @@ extern AVCodec mp3_decoder; ...@@ -2004,6 +2005,7 @@ extern AVCodec mp3_decoder;
extern AVCodec mp3adu_decoder; extern AVCodec mp3adu_decoder;
extern AVCodec mp3on4_decoder; extern AVCodec mp3on4_decoder;
extern AVCodec qdm2_decoder; extern AVCodec qdm2_decoder;
extern AVCodec cook_decoder;
extern AVCodec mace3_decoder; extern AVCodec mace3_decoder;
extern AVCodec mace6_decoder; extern AVCodec mace6_decoder;
extern AVCodec huffyuv_decoder; extern AVCodec huffyuv_decoder;
......
This diff is collapsed.
This diff is collapsed.
...@@ -228,41 +228,19 @@ static int ra288_decode_frame(AVCodecContext * avctx, ...@@ -228,41 +228,19 @@ static int ra288_decode_frame(AVCodecContext * avctx,
void *data, int *data_size, void *data, int *data_size,
uint8_t * buf, int buf_size) uint8_t * buf, int buf_size)
{ {
if(avctx->extradata_size>=6)
{
//((short*)(avctx->extradata))[0]; /* subpacket size */
//((short*)(avctx->extradata))[1]; /* subpacket height */
//((short*)(avctx->extradata))[2]; /* subpacket flavour */
//((short*)(avctx->extradata))[3]; /* coded frame size */
//((short*)(avctx->extradata))[4]; /* codec's data length */
//((short*)(avctx->extradata))[5...] /* codec's data */
int bret;
void *datao; void *datao;
int w=avctx->block_align; /* 228 */
int h=((short*)(avctx->extradata))[1]; /* 12 */ if (buf_size < avctx->block_align)
int cfs=((short*)(avctx->extradata))[3]; /* coded frame size 38 */
int i,j;
if(buf_size<w*h)
{ {
av_log(avctx, AV_LOG_ERROR, "ffra288: Error! Input buffer is too small [%d<%d]\n",buf_size,w*h); av_log(avctx, AV_LOG_ERROR, "ffra288: Error! Input buffer is too small [%d<%d]\n",buf_size,avctx->block_align);
return 0; return 0;
} }
datao = data; datao = data;
bret = 0; data = decode_block(avctx, buf, (signed short *)data, avctx->block_align);
for (j = 0; j < h/2; j++)
for (i = 0; i < h; i++)
{
data=decode_block(avctx,&buf[j*cfs+cfs*i*h/2],(signed short *)data,cfs);
bret += cfs;
}
*data_size = (char *)data - (char *)datao; *data_size = (char *)data - (char *)datao;
return bret; return avctx->block_align;
}
else
{
av_log(avctx, AV_LOG_ERROR, "ffra288: Error: need extra data!!!\n");
return 0;
}
} }
AVCodec ra_288_decoder = AVCodec ra_288_decoder =
......
...@@ -5,8 +5,8 @@ ...@@ -5,8 +5,8 @@
extern "C" { extern "C" {
#endif #endif
#define LIBAVFORMAT_VERSION_INT ((49<<16)+(2<<8)+0) #define LIBAVFORMAT_VERSION_INT ((50<<16)+(0<<8)+0)
#define LIBAVFORMAT_VERSION 49.2.0 #define LIBAVFORMAT_VERSION 50.0.0
#define LIBAVFORMAT_BUILD LIBAVFORMAT_VERSION_INT #define LIBAVFORMAT_BUILD LIBAVFORMAT_VERSION_INT
#define LIBAVFORMAT_IDENT "Lavf" AV_STRINGIFY(LIBAVFORMAT_VERSION) #define LIBAVFORMAT_IDENT "Lavf" AV_STRINGIFY(LIBAVFORMAT_VERSION)
......
...@@ -42,6 +42,14 @@ typedef struct { ...@@ -42,6 +42,14 @@ typedef struct {
int old_format; int old_format;
int current_stream; int current_stream;
int remaining_len; int remaining_len;
/// Audio descrambling matrix parameters
uint8_t *audiobuf; ///< place to store reordered audio data
int64_t audiotimestamp; ///< Audio packet timestamp
int sub_packet_cnt; // Subpacket counter, used while reading
int sub_packet_size, sub_packet_h, coded_framesize; ///< Descrambling parameters from container
int audio_stream_num; ///< Stream number for audio packets
int audio_pkt_cnt; ///< Output packet counter
int audio_framesize; /// Audio frame size from container
} RMContext; } RMContext;
#ifdef CONFIG_MUXERS #ifdef CONFIG_MUXERS
...@@ -478,6 +486,7 @@ static void get_str8(ByteIOContext *pb, char *buf, int buf_size) ...@@ -478,6 +486,7 @@ static void get_str8(ByteIOContext *pb, char *buf, int buf_size)
static void rm_read_audio_stream_info(AVFormatContext *s, AVStream *st, static void rm_read_audio_stream_info(AVFormatContext *s, AVStream *st,
int read_all) int read_all)
{ {
RMContext *rm = s->priv_data;
ByteIOContext *pb = &s->pb; ByteIOContext *pb = &s->pb;
char buf[128]; char buf[128];
uint32_t version; uint32_t version;
...@@ -500,39 +509,60 @@ static void rm_read_audio_stream_info(AVFormatContext *s, AVStream *st, ...@@ -500,39 +509,60 @@ static void rm_read_audio_stream_info(AVFormatContext *s, AVStream *st,
st->codec->codec_type = CODEC_TYPE_AUDIO; st->codec->codec_type = CODEC_TYPE_AUDIO;
st->codec->codec_id = CODEC_ID_RA_144; st->codec->codec_id = CODEC_ID_RA_144;
} else { } else {
int flavor, sub_packet_h, coded_framesize; int flavor, sub_packet_h, coded_framesize, sub_packet_size;
/* old version (4) */ /* old version (4) */
get_be32(pb); /* .ra4 */ get_be32(pb); /* .ra4 */
get_be32(pb); /* data size */ get_be32(pb); /* data size */
get_be16(pb); /* version2 */ get_be16(pb); /* version2 */
get_be32(pb); /* header size */ get_be32(pb); /* header size */
flavor= get_be16(pb); /* add codec info / flavor */ flavor= get_be16(pb); /* add codec info / flavor */
coded_framesize= get_be32(pb); /* coded frame size */ rm->coded_framesize = coded_framesize = get_be32(pb); /* coded frame size */
get_be32(pb); /* ??? */ get_be32(pb); /* ??? */
get_be32(pb); /* ??? */ get_be32(pb); /* ??? */
get_be32(pb); /* ??? */ get_be32(pb); /* ??? */
sub_packet_h= get_be16(pb); /* 1 */ rm->sub_packet_h = sub_packet_h = get_be16(pb); /* 1 */
st->codec->block_align= get_be16(pb); /* frame size */ st->codec->block_align= get_be16(pb); /* frame size */
get_be16(pb); /* sub packet size */ rm->sub_packet_size = sub_packet_size = get_be16(pb); /* sub packet size */
get_be16(pb); /* ??? */ get_be16(pb); /* ??? */
if (((version >> 16) & 0xff) == 5) {
get_be16(pb); get_be16(pb); get_be16(pb); }
st->codec->sample_rate = get_be16(pb); st->codec->sample_rate = get_be16(pb);
get_be32(pb); get_be32(pb);
st->codec->channels = get_be16(pb); st->codec->channels = get_be16(pb);
if (((version >> 16) & 0xff) == 5) {
get_be32(pb);
buf[0] = get_byte(pb);
buf[1] = get_byte(pb);
buf[2] = get_byte(pb);
buf[3] = get_byte(pb);
buf[4] = 0;
} else {
get_str8(pb, buf, sizeof(buf)); /* desc */ get_str8(pb, buf, sizeof(buf)); /* desc */
get_str8(pb, buf, sizeof(buf)); /* desc */ get_str8(pb, buf, sizeof(buf)); /* desc */
}
st->codec->codec_type = CODEC_TYPE_AUDIO; st->codec->codec_type = CODEC_TYPE_AUDIO;
if (!strcmp(buf, "dnet")) { if (!strcmp(buf, "dnet")) {
st->codec->codec_id = CODEC_ID_AC3; st->codec->codec_id = CODEC_ID_AC3;
} else if (!strcmp(buf, "28_8")) { } else if (!strcmp(buf, "28_8")) {
st->codec->codec_id = CODEC_ID_RA_288; st->codec->codec_id = CODEC_ID_RA_288;
st->codec->extradata_size= 10; st->codec->extradata_size= 0;
rm->audio_framesize = st->codec->block_align;
st->codec->block_align = coded_framesize;
rm->audiobuf = av_malloc(rm->audio_framesize * sub_packet_h);
} else if (!strcmp(buf, "cook")) {
int codecdata_length, i;
get_be16(pb); get_byte(pb);
if (((version >> 16) & 0xff) == 5)
get_byte(pb);
codecdata_length = get_be32(pb);
st->codec->codec_id = CODEC_ID_COOK;
st->codec->extradata_size= codecdata_length;
st->codec->extradata= av_mallocz(st->codec->extradata_size); st->codec->extradata= av_mallocz(st->codec->extradata_size);
/* this is completly braindead and broken, the idiot who added this codec and endianness for(i = 0; i < codecdata_length; i++)
specific reordering to mplayer and libavcodec/ra288.c should be drowned in a see of cola */ ((uint8_t*)st->codec->extradata)[i] = get_byte(pb);
//FIXME pass the unpermutated extradata rm->audio_framesize = st->codec->block_align;
((uint16_t*)st->codec->extradata)[1]= sub_packet_h; st->codec->block_align = rm->sub_packet_size;
((uint16_t*)st->codec->extradata)[2]= flavor; rm->audiobuf = av_malloc(rm->audio_framesize * sub_packet_h);
((uint16_t*)st->codec->extradata)[3]= coded_framesize;
} else { } else {
st->codec->codec_id = CODEC_ID_NONE; st->codec->codec_id = CODEC_ID_NONE;
pstrcpy(st->codec->codec_name, sizeof(st->codec->codec_name), pstrcpy(st->codec->codec_name, sizeof(st->codec->codec_name),
...@@ -819,6 +849,16 @@ static int rm_read_packet(AVFormatContext *s, AVPacket *pkt) ...@@ -819,6 +849,16 @@ static int rm_read_packet(AVFormatContext *s, AVPacket *pkt)
} }
pkt->size = len; pkt->size = len;
st = s->streams[0]; st = s->streams[0];
} else if (rm->audio_pkt_cnt) {
// If there are queued audio packet return them first
st = s->streams[rm->audio_stream_num];
av_new_packet(pkt, st->codec->block_align);
memcpy(pkt->data, rm->audiobuf + st->codec->block_align *
(rm->sub_packet_h * rm->audio_framesize / st->codec->block_align - rm->audio_pkt_cnt),
st->codec->block_align);
rm->audio_pkt_cnt--;
pkt->flags = 0;
pkt->stream_index = rm->audio_stream_num;
} else { } else {
int seq=1; int seq=1;
resync: resync:
...@@ -850,15 +890,57 @@ resync: ...@@ -850,15 +890,57 @@ resync:
if(len2 && len2<len) if(len2 && len2<len)
len=len2; len=len2;
rm->remaining_len-= len; rm->remaining_len-= len;
av_get_packet(pb, pkt, len);
}
if (st->codec->codec_type == CODEC_TYPE_AUDIO) {
if ((st->codec->codec_id == CODEC_ID_RA_288) ||
(st->codec->codec_id == CODEC_ID_COOK)) {
int x;
int sps = rm->sub_packet_size;
int cfs = rm->coded_framesize;
int h = rm->sub_packet_h;
int y = rm->sub_packet_cnt;
int w = rm->audio_framesize;
if (flags & 2)
y = rm->sub_packet_cnt = 0;
if (!y)
rm->audiotimestamp = timestamp;
switch(st->codec->codec_id) {
case CODEC_ID_RA_288:
for (x = 0; x < h/2; x++)
get_buffer(pb, rm->audiobuf+x*2*w+y*cfs, cfs);
break;
case CODEC_ID_COOK:
for (x = 0; x < w/sps; x++)
get_buffer(pb, rm->audiobuf+sps*(h*x+((h+1)/2)*(y&1)+(y>>1)), sps);
break;
}
if (++(rm->sub_packet_cnt) < h)
goto resync;
else {
rm->sub_packet_cnt = 0;
rm->audio_stream_num = i;
rm->audio_pkt_cnt = h * w / st->codec->block_align - 1;
// Release first audio packet
av_new_packet(pkt, st->codec->block_align);
memcpy(pkt->data, rm->audiobuf, st->codec->block_align);
timestamp = rm->audiotimestamp;
flags = 2; // Mark first packet as keyframe
}
} else
av_get_packet(pb, pkt, len);
} }
if( (st->discard >= AVDISCARD_NONKEY && !(flags&2)) if( (st->discard >= AVDISCARD_NONKEY && !(flags&2))
|| st->discard >= AVDISCARD_ALL){ || st->discard >= AVDISCARD_ALL){
url_fskip(pb, len); av_free_packet(pkt);
goto resync; goto resync;
} }
av_get_packet(pb, pkt, len);
pkt->stream_index = i; pkt->stream_index = i;
#if 0 #if 0
...@@ -896,6 +978,9 @@ resync: ...@@ -896,6 +978,9 @@ resync:
static int rm_read_close(AVFormatContext *s) static int rm_read_close(AVFormatContext *s)
{ {
RMContext *rm = s->priv_data;
av_free(rm->audiobuf);
return 0; return 0;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment