mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-01-08 13:22:53 +02:00
change extradata format for vorbis
Originally committed as revision 4235 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
e817a73daa
commit
ad2b531d3f
@ -2357,6 +2357,8 @@ extern void av_log_set_callback(void (*)(void*, int, const char*, va_list));
|
|||||||
((uint8_t*)(x))[0])
|
((uint8_t*)(x))[0])
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
extern unsigned int av_xiphlacing(unsigned char *s, unsigned int v);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -49,6 +49,7 @@ static int oggvorbis_encode_init(AVCodecContext *avccontext) {
|
|||||||
OggVorbisContext *context = avccontext->priv_data ;
|
OggVorbisContext *context = avccontext->priv_data ;
|
||||||
ogg_packet header, header_comm, header_code;
|
ogg_packet header, header_comm, header_code;
|
||||||
uint8_t *p;
|
uint8_t *p;
|
||||||
|
unsigned int offset, len;
|
||||||
|
|
||||||
vorbis_info_init(&context->vi) ;
|
vorbis_info_init(&context->vi) ;
|
||||||
if(oggvorbis_init_encoder(&context->vi, avccontext) < 0) {
|
if(oggvorbis_init_encoder(&context->vi, avccontext) < 0) {
|
||||||
@ -64,22 +65,21 @@ static int oggvorbis_encode_init(AVCodecContext *avccontext) {
|
|||||||
vorbis_analysis_headerout(&context->vd, &context->vc, &header,
|
vorbis_analysis_headerout(&context->vd, &context->vc, &header,
|
||||||
&header_comm, &header_code);
|
&header_comm, &header_code);
|
||||||
|
|
||||||
avccontext->extradata_size= 3*2 + header.bytes + header_comm.bytes + header_code.bytes;
|
len = header.bytes + header_comm.bytes + header_code.bytes;
|
||||||
p= avccontext->extradata= av_mallocz(avccontext->extradata_size);
|
avccontext->extradata_size= 64 + len + len/255;
|
||||||
|
p = avccontext->extradata= av_mallocz(avccontext->extradata_size);
|
||||||
*(p++) = header.bytes>>8;
|
p[0] = 2;
|
||||||
*(p++) = header.bytes&0xFF;
|
offset = 1;
|
||||||
memcpy(p, header.packet, header.bytes);
|
offset += av_xiphlacing(&p[offset], header.bytes);
|
||||||
p += header.bytes;
|
offset += av_xiphlacing(&p[offset], header_comm.bytes);
|
||||||
|
memcpy(&p[offset], header.packet, header.bytes);
|
||||||
*(p++) = header_comm.bytes>>8;
|
offset += header.bytes;
|
||||||
*(p++) = header_comm.bytes&0xFF;
|
memcpy(&p[offset], header_comm.packet, header_comm.bytes);
|
||||||
memcpy(p, header_comm.packet, header_comm.bytes);
|
offset += header_comm.bytes;
|
||||||
p += header_comm.bytes;
|
memcpy(&p[offset], header_code.packet, header_code.bytes);
|
||||||
|
offset += header_code.bytes;
|
||||||
*(p++) = header_code.bytes>>8;
|
avccontext->extradata_size = offset;
|
||||||
*(p++) = header_code.bytes&0xFF;
|
avccontext->extradata= av_realloc(avccontext->extradata, avccontext->extradata_size);
|
||||||
memcpy(p, header_code.packet, header_code.bytes);
|
|
||||||
|
|
||||||
/* vorbis_block_clear(&context->vb);
|
/* vorbis_block_clear(&context->vb);
|
||||||
vorbis_dsp_clear(&context->vd);
|
vorbis_dsp_clear(&context->vd);
|
||||||
@ -184,19 +184,54 @@ AVCodec oggvorbis_encoder = {
|
|||||||
static int oggvorbis_decode_init(AVCodecContext *avccontext) {
|
static int oggvorbis_decode_init(AVCodecContext *avccontext) {
|
||||||
OggVorbisContext *context = avccontext->priv_data ;
|
OggVorbisContext *context = avccontext->priv_data ;
|
||||||
uint8_t *p= avccontext->extradata;
|
uint8_t *p= avccontext->extradata;
|
||||||
int i;
|
int i, hsizes[3];
|
||||||
|
unsigned char *headers[3], *extradata = avccontext->extradata;
|
||||||
|
unsigned int offset;
|
||||||
|
|
||||||
vorbis_info_init(&context->vi) ;
|
vorbis_info_init(&context->vi) ;
|
||||||
vorbis_comment_init(&context->vc) ;
|
vorbis_comment_init(&context->vc) ;
|
||||||
|
|
||||||
|
if(! avccontext->extradata_size || ! p) {
|
||||||
|
av_log(avccontext, AV_LOG_ERROR, "vorbis extradata absent\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(*p != 2) {
|
||||||
|
av_log(avccontext, AV_LOG_ERROR,
|
||||||
|
"vorbis initial header len is wrong: %d\n", *p);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
offset = 1;
|
||||||
|
p++;
|
||||||
|
for(i=0; i<2; i++) {
|
||||||
|
hsizes[i] = 0;
|
||||||
|
while((*p == 0xFF) && (offset < avccontext->extradata_size)) {
|
||||||
|
hsizes[i] += 0xFF;
|
||||||
|
offset++;
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
if(offset >= avccontext->extradata_size - 1) {
|
||||||
|
av_log(avccontext, AV_LOG_ERROR, "vorbis header sizes damaged\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
hsizes[i] += *p;
|
||||||
|
offset++;
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
hsizes[2] = avccontext->extradata_size - hsizes[0] - hsizes[1] - offset;
|
||||||
|
#if 0
|
||||||
|
av_log(avccontext, AV_LOG_DEBUG,
|
||||||
|
"vorbis header sizes: %d, %d, %d, / extradata_len is %d \n",
|
||||||
|
hsizes[0], hsizes[1], hsizes[2], avccontext->extradata_size);
|
||||||
|
#endif
|
||||||
|
headers[0] = extradata + offset;
|
||||||
|
headers[1] = extradata + offset + hsizes[0];
|
||||||
|
headers[2] = extradata + offset + hsizes[0] + hsizes[1];
|
||||||
|
|
||||||
for(i=0; i<3; i++){
|
for(i=0; i<3; i++){
|
||||||
context->op.b_o_s= i==0;
|
context->op.b_o_s= i==0;
|
||||||
context->op.bytes= *(p++)<<8;
|
context->op.bytes = hsizes[i];
|
||||||
context->op.bytes+=*(p++);
|
context->op.packet = headers[i];
|
||||||
context->op.packet= p;
|
if(vorbis_synthesis_headerin(&context->vi, &context->vc, &context->op)<0){
|
||||||
p += context->op.bytes;
|
|
||||||
|
|
||||||
if(vorbis_synthesis_headerin(&context->vi, &context->vc, &context->op)<0){
|
|
||||||
av_log(avccontext, AV_LOG_ERROR, "%d. vorbis header damaged\n", i+1);
|
av_log(avccontext, AV_LOG_ERROR, "%d. vorbis header damaged\n", i+1);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1015,3 +1015,17 @@ int avcodec_thread_init(AVCodecContext *s, int thread_count){
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
unsigned int av_xiphlacing(unsigned char *s, unsigned int v)
|
||||||
|
{
|
||||||
|
unsigned int n = 0;
|
||||||
|
|
||||||
|
while(v >= 0xff) {
|
||||||
|
*s++ = 0xff;
|
||||||
|
v -= 0xff;
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
*s = v;
|
||||||
|
n++;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
@ -2243,44 +2243,13 @@ matroska_read_header (AVFormatContext *s,
|
|||||||
/* codec_id = CODEC_ID_DTS; */
|
/* codec_id = CODEC_ID_DTS; */
|
||||||
else if (!strcmp(track->codec_id,
|
else if (!strcmp(track->codec_id,
|
||||||
MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
|
MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
|
||||||
unsigned char *p = track->codec_priv, *cdp;
|
extradata_size = track->codec_priv_size;
|
||||||
int cps = track->codec_priv_size;
|
if(extradata_size) {
|
||||||
int nf, s[3], cds;
|
extradata = av_malloc(extradata_size);
|
||||||
int i;
|
if(extradata == NULL)
|
||||||
|
return AVERROR_NOMEM;
|
||||||
nf = *p++;
|
memcpy(extradata, track->codec_priv, extradata_size);
|
||||||
cps--;
|
|
||||||
|
|
||||||
if(nf != 2)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for(i = 0; i < 2; i++){
|
|
||||||
int xv;
|
|
||||||
s[i] = 0;
|
|
||||||
do {
|
|
||||||
xv = *p++;
|
|
||||||
s[i] += xv;
|
|
||||||
cps--;
|
|
||||||
} while(xv == 255);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
s[2] = cps - s[0] - s[1];
|
|
||||||
|
|
||||||
cds = cps + 6;
|
|
||||||
extradata = cdp = av_malloc(cds);
|
|
||||||
if(extradata == NULL)
|
|
||||||
return AVERROR_NOMEM;
|
|
||||||
extradata_size = cds;
|
|
||||||
|
|
||||||
for(i = 0; i < 3; i++){
|
|
||||||
*cdp++ = s[i] >> 8;
|
|
||||||
*cdp++ = s[i] & 0xff;
|
|
||||||
memcpy(cdp, p, s[i]);
|
|
||||||
cdp += s[i];
|
|
||||||
p += s[i];
|
|
||||||
cps -= s[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
codec_id = CODEC_ID_VORBIS;
|
codec_id = CODEC_ID_VORBIS;
|
||||||
} else if (!strcmp(track->codec_id,
|
} else if (!strcmp(track->codec_id,
|
||||||
MATROSKA_CODEC_ID_AUDIO_MPEG2) ||
|
MATROSKA_CODEC_ID_AUDIO_MPEG2) ||
|
||||||
|
@ -126,25 +126,56 @@ vorbis_comment (AVFormatContext * as, char *buf, int size)
|
|||||||
* [framing_flag] = read one bit | Not Used
|
* [framing_flag] = read one bit | Not Used
|
||||||
* */
|
* */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned int len[3];
|
||||||
|
unsigned char *packet[3];
|
||||||
|
} oggvorbis_private_t;
|
||||||
|
|
||||||
|
|
||||||
|
static unsigned int
|
||||||
|
fixup_vorbis_headers(AVFormatContext * as, oggvorbis_private_t *priv,
|
||||||
|
void **buf)
|
||||||
|
{
|
||||||
|
int i,offset, len;
|
||||||
|
unsigned char *ptr;
|
||||||
|
|
||||||
|
len = priv->len[0] + priv->len[1] + priv->len[2];
|
||||||
|
ptr = *buf = av_mallocz(len + len/255 + 64);
|
||||||
|
|
||||||
|
ptr[0] = 2;
|
||||||
|
offset = 1;
|
||||||
|
offset += av_xiphlacing(&ptr[offset], priv->len[0]);
|
||||||
|
offset += av_xiphlacing(&ptr[offset], priv->len[1]);
|
||||||
|
for(i = 0; i < 3; i++) {
|
||||||
|
memcpy(&ptr[offset], priv->packet[i], priv->len[i]);
|
||||||
|
offset += priv->len[i];
|
||||||
|
}
|
||||||
|
*buf = av_realloc(*buf, offset);
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
vorbis_header (AVFormatContext * s, int idx)
|
vorbis_header (AVFormatContext * s, int idx)
|
||||||
{
|
{
|
||||||
ogg_t *ogg = s->priv_data;
|
ogg_t *ogg = s->priv_data;
|
||||||
ogg_stream_t *os = ogg->streams + idx;
|
ogg_stream_t *os = ogg->streams + idx;
|
||||||
AVStream *st = s->streams[idx];
|
AVStream *st = s->streams[idx];
|
||||||
int cds = st->codec.extradata_size + os->psize + 2;
|
oggvorbis_private_t *priv;
|
||||||
uint8_t *cdp;
|
|
||||||
|
|
||||||
if (os->seq > 2)
|
if (os->seq > 2)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
st->codec.extradata = av_realloc (st->codec.extradata, cds);
|
if(os->seq == 0) {
|
||||||
cdp = st->codec.extradata + st->codec.extradata_size;
|
os->private = av_mallocz(sizeof(oggvorbis_private_t));
|
||||||
*cdp++ = os->psize >> 8;
|
if(!os->private)
|
||||||
*cdp++ = os->psize & 0xff;
|
return 0;
|
||||||
memcpy (cdp, os->buf + os->pstart, os->psize);
|
}
|
||||||
st->codec.extradata_size = cds;
|
|
||||||
|
|
||||||
|
priv = os->private;
|
||||||
|
priv->len[os->seq] = os->psize;
|
||||||
|
priv->packet[os->seq] = av_mallocz(os->psize);
|
||||||
|
memcpy(priv->packet[os->seq], os->buf + os->pstart, os->psize);
|
||||||
if (os->buf[os->pstart] == 1) {
|
if (os->buf[os->pstart] == 1) {
|
||||||
uint8_t *p = os->buf + os->pstart + 11; //skip up to the audio channels
|
uint8_t *p = os->buf + os->pstart + 11; //skip up to the audio channels
|
||||||
st->codec.channels = *p++;
|
st->codec.channels = *p++;
|
||||||
@ -157,6 +188,9 @@ vorbis_header (AVFormatContext * s, int idx)
|
|||||||
|
|
||||||
} else if (os->buf[os->pstart] == 3) {
|
} else if (os->buf[os->pstart] == 3) {
|
||||||
vorbis_comment (s, os->buf + os->pstart + 7, os->psize - 8);
|
vorbis_comment (s, os->buf + os->pstart + 7, os->psize - 8);
|
||||||
|
} else {
|
||||||
|
st->codec.extradata_size =
|
||||||
|
fixup_vorbis_headers(s, priv, &st->codec.extradata);
|
||||||
}
|
}
|
||||||
|
|
||||||
return os->seq < 3;
|
return os->seq < 3;
|
||||||
|
Loading…
Reference in New Issue
Block a user