X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Frmdec.c;h=436a7e08f2a593735d50e15ba38ed34c5f8eede1;hb=d20d1449e0eea245c483c0b97faf38df5092ff2f;hp=d5cedbb8a8ef9fd124fb92c193802ff7cc28db2e;hpb=0dae3e13e39d8caaedeabb4b20c31da6cad4a908;p=ffmpeg diff --git a/libavformat/rmdec.c b/libavformat/rmdec.c index d5cedbb8a8e..436a7e08f2a 100644 --- a/libavformat/rmdec.c +++ b/libavformat/rmdec.c @@ -49,23 +49,6 @@ typedef struct { int audio_pkt_cnt; ///< Output packet counter } RMDemuxContext; -static const AVCodecTag rm_codec_tags[] = { - { CODEC_ID_RV10, MKTAG('R','V','1','0') }, - { CODEC_ID_RV20, MKTAG('R','V','2','0') }, - { CODEC_ID_RV20, MKTAG('R','V','T','R') }, - { CODEC_ID_RV30, MKTAG('R','V','3','0') }, - { CODEC_ID_RV40, MKTAG('R','V','4','0') }, - { CODEC_ID_AC3, MKTAG('d','n','e','t') }, - { CODEC_ID_RA_144, MKTAG('l','p','c','J') }, - { CODEC_ID_RA_288, MKTAG('2','8','_','8') }, - { CODEC_ID_COOK, MKTAG('c','o','o','k') }, - { CODEC_ID_ATRAC3, MKTAG('a','t','r','c') }, - { CODEC_ID_SIPR, MKTAG('s','i','p','r') }, - { CODEC_ID_AAC, MKTAG('r','a','a','c') }, - { CODEC_ID_AAC, MKTAG('r','a','c','p') }, - { 0 }, -}; - static const unsigned char sipr_swaps[38][2] = { { 0, 63 }, { 1, 22 }, { 2, 44 }, { 3, 90 }, { 5, 81 }, { 7, 31 }, { 8, 86 }, { 9, 58 }, @@ -79,7 +62,7 @@ static const unsigned char sipr_swaps[38][2] = { { 67, 83 }, { 77, 80 } }; -static const unsigned char sipr_subpk_size[4] = { 29, 19, 37, 20 }; +const unsigned char ff_sipr_subpk_size[4] = { 29, 19, 37, 20 }; static inline void get_strl(ByteIOContext *pb, char *buf, int buf_size, int len) { @@ -106,7 +89,7 @@ static int rm_read_extradata(ByteIOContext *pb, AVCodecContext *avctx, unsigned return -1; avctx->extradata = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE); if (!avctx->extradata) - return AVERROR_NOMEM; + return AVERROR(ENOMEM); avctx->extradata_size = get_buffer(pb, avctx->extradata, size); memset(avctx->extradata + avctx->extradata_size, 0, FF_INPUT_BUFFER_PADDING_SIZE); if (avctx->extradata_size != size) @@ -121,7 +104,7 @@ static void rm_read_metadata(AVFormatContext *s, int wide) for (i=0; ipb) : get_byte(s->pb); get_strl(s->pb, buf, sizeof(buf), len); - av_metadata_set(&s->metadata, ff_rm_metadata[i], buf); + av_metadata_set2(&s->metadata, ff_rm_metadata[i], buf, 0); } } @@ -161,7 +144,7 @@ static int rm_read_audio_stream_info(AVFormatContext *s, ByteIOContext *pb, url_fskip(pb, header_size + startpos - url_ftell(pb)); st->codec->sample_rate = 8000; st->codec->channels = 1; - st->codec->codec_type = CODEC_TYPE_AUDIO; + st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = CODEC_ID_RA_144; } else { int flavor, sub_packet_h, coded_framesize, sub_packet_size; @@ -195,9 +178,10 @@ static int rm_read_audio_stream_info(AVFormatContext *s, ByteIOContext *pb, 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 = AVMEDIA_TYPE_AUDIO; st->codec->codec_tag = AV_RL32(buf); - st->codec->codec_id = ff_codec_get_id(rm_codec_tags, st->codec->codec_tag); + st->codec->codec_id = ff_codec_get_id(ff_rm_codec_tags, + st->codec->codec_tag); switch (st->codec->codec_id) { case CODEC_ID_AC3: st->need_parsing = AVSTREAM_PARSE_FULL; @@ -226,10 +210,6 @@ static int rm_read_audio_stream_info(AVFormatContext *s, ByteIOContext *pb, return -1; } - if (!strcmp(buf, "cook")) st->codec->codec_id = CODEC_ID_COOK; - else if (!strcmp(buf, "sipr")) st->codec->codec_id = CODEC_ID_SIPR; - else st->codec->codec_id = CODEC_ID_ATRAC3; - ast->audio_framesize = st->codec->block_align; if (st->codec->codec_id == CODEC_ID_SIPR) { if (flavor > 3) { @@ -237,7 +217,7 @@ static int rm_read_audio_stream_info(AVFormatContext *s, ByteIOContext *pb, flavor); return -1; } - st->codec->block_align = sipr_subpk_size[flavor]; + st->codec->block_align = ff_sipr_subpk_size[flavor]; } else { if(sub_packet_size <= 0){ av_log(s, AV_LOG_ERROR, "sub_packet_size is invalid\n"); @@ -245,7 +225,7 @@ static int rm_read_audio_stream_info(AVFormatContext *s, ByteIOContext *pb, } st->codec->block_align = ast->sub_packet_size; } - if ((ret = rm_read_extradata(s->pb, st->codec, codecdata_length)) < 0) + if ((ret = rm_read_extradata(pb, st->codec, codecdata_length)) < 0) return ret; if(ast->audio_framesize >= UINT_MAX / sub_packet_h){ @@ -259,7 +239,6 @@ static int rm_read_audio_stream_info(AVFormatContext *s, ByteIOContext *pb, get_be16(pb); get_byte(pb); if (version == 5) get_byte(pb); - st->codec->codec_id = CODEC_ID_AAC; codecdata_length = get_be32(pb); if(codecdata_length + FF_INPUT_BUFFER_PADDING_SIZE <= (unsigned)codecdata_length){ av_log(s, AV_LOG_ERROR, "codecdata_length too large\n"); @@ -267,7 +246,7 @@ static int rm_read_audio_stream_info(AVFormatContext *s, ByteIOContext *pb, } if (codecdata_length >= 1) { get_byte(pb); - if ((ret = rm_read_extradata(s->pb, st->codec, codecdata_length - 1)) < 0) + if ((ret = rm_read_extradata(pb, st->codec, codecdata_length - 1)) < 0) return ret; } break; @@ -308,7 +287,8 @@ ff_rm_read_mdpr_codecdata (AVFormatContext *s, ByteIOContext *pb, goto skip; } st->codec->codec_tag = get_le32(pb); - st->codec->codec_id = ff_codec_get_id(rm_codec_tags, st->codec->codec_tag); + st->codec->codec_id = ff_codec_get_id(ff_rm_codec_tags, + st->codec->codec_tag); // av_log(s, AV_LOG_DEBUG, "%X %X\n", st->codec->codec_tag, MKTAG('R', 'V', '2', '0')); if (st->codec->codec_id == CODEC_ID_NONE) goto fail1; @@ -316,23 +296,25 @@ ff_rm_read_mdpr_codecdata (AVFormatContext *s, ByteIOContext *pb, st->codec->height = get_be16(pb); st->codec->time_base.num= 1; fps= get_be16(pb); - st->codec->codec_type = CODEC_TYPE_VIDEO; + st->codec->codec_type = AVMEDIA_TYPE_VIDEO; get_be32(pb); fps2= get_be16(pb); get_be16(pb); - if ((ret = rm_read_extradata(s->pb, st->codec, codec_data_size - (url_ftell(pb) - codec_pos))) < 0) + if ((ret = rm_read_extradata(pb, st->codec, codec_data_size - (url_ftell(pb) - codec_pos))) < 0) return ret; // av_log(s, AV_LOG_DEBUG, "fps= %d fps2= %d\n", fps, fps2); st->codec->time_base.den = fps * st->codec->time_base.num; //XXX: do we really need that? - switch(((uint8_t*)st->codec->extradata)[4]>>4){ + switch(st->codec->extradata[4]>>4){ case 1: st->codec->codec_id = CODEC_ID_RV10; break; case 2: st->codec->codec_id = CODEC_ID_RV20; break; case 3: st->codec->codec_id = CODEC_ID_RV30; break; case 4: st->codec->codec_id = CODEC_ID_RV40; break; - default: goto fail1; + default: + av_log(st->codec, AV_LOG_ERROR, "extra:%02X %02X %02X %02X %02X\n", st->codec->extradata[0], st->codec->extradata[1], st->codec->extradata[2], st->codec->extradata[3], st->codec->extradata[4]); + goto fail1; } } @@ -477,7 +459,7 @@ static int rm_read_header(AVFormatContext *s, AVFormatParameters *ap) st->duration = duration; get_str8(pb, buf, sizeof(buf)); /* desc */ get_str8(pb, buf, sizeof(buf)); /* mimetype */ - st->codec->codec_type = CODEC_TYPE_DATA; + st->codec->codec_type = AVMEDIA_TYPE_DATA; st->priv_data = ff_rm_alloc_rmstream(); if (ff_rm_read_mdpr_codecdata(s, s->pb, st, st->priv_data, get_be32(pb)) < 0) @@ -499,7 +481,8 @@ static int rm_read_header(AVFormatContext *s, AVFormatParameters *ap) if (!data_off) data_off = url_ftell(pb) - 18; - if (indx_off && url_fseek(pb, indx_off, SEEK_SET) >= 0) { + if (indx_off && !url_is_streamed(pb) && !(s->flags & AVFMT_FLAG_IGNIDX) && + url_fseek(pb, indx_off, SEEK_SET) >= 0) { rm_read_index(s); url_fseek(pb, data_off + 18, SEEK_SET); } @@ -533,7 +516,7 @@ static int sync(AVFormatContext *s, int64_t *timestamp, int *flags, int *stream_ uint32_t state=0xFFFFFFFF; while(!url_feof(pb)){ - int len, num, res, i; + int len, num, i; *pos= url_ftell(pb) - 3; if(rm->remaining_len > 0){ num= rm->current_stream; @@ -560,6 +543,9 @@ static int sync(AVFormatContext *s, int64_t *timestamp, int *flags, int *stream_ if(len<0) continue; goto skip; + } else if (state == MKBETAG('D','A','T','A')) { + av_log(s, AV_LOG_WARNING, + "DATA tag in middle of chunk, file may be broken.\n"); } if(state > (unsigned)0xFFFF || state <= 12) @@ -569,7 +555,7 @@ static int sync(AVFormatContext *s, int64_t *timestamp, int *flags, int *stream_ num = get_be16(pb); *timestamp = get_be32(pb); - res= get_byte(pb); /* reserved */ + get_byte(pb); /* reserved */ *flags = get_byte(pb); /* flags */ } for(i=0;inb_streams;i++) { @@ -691,16 +677,14 @@ rm_ac3_swap_bytes (AVStream *st, AVPacket *pkt) * Perform 4-bit block reordering for SIPR data. * @todo This can be optimized, e.g. use memcpy() if data blocks are aligned */ -static void -rm_reorder_sipr_data (RMStream *ast) +void ff_rm_reorder_sipr_data(uint8_t *buf, int sub_packet_h, int framesize) { - int n, bs = ast->sub_packet_h * ast->audio_framesize * 2 / 96; // nibbles per subpacket + int n, bs = sub_packet_h * framesize * 2 / 96; // nibbles per subpacket for (n = 0; n < 38; n++) { int j; int i = bs * sipr_swaps[n][0]; int o = bs * sipr_swaps[n][1]; - uint8_t *buf = ast->pkt.data; /* swap 4bit-nibbles of block 'i' with 'o' */ for (j = 0; j < bs; j++, i++, o++) { @@ -722,11 +706,11 @@ ff_rm_parse_packet (AVFormatContext *s, ByteIOContext *pb, { RMDemuxContext *rm = s->priv_data; - if (st->codec->codec_type == CODEC_TYPE_VIDEO) { + if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { rm->current_stream= st->id; if(rm_assemble_video_frame(s, pb, rm, ast, pkt, len, seq)) return -1; //got partial frame - } else if (st->codec->codec_type == CODEC_TYPE_AUDIO) { + } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { if ((st->codec->codec_id == CODEC_ID_RA_288) || (st->codec->codec_id == CODEC_ID_COOK) || (st->codec->codec_id == CODEC_ID_ATRAC3) || @@ -761,7 +745,7 @@ ff_rm_parse_packet (AVFormatContext *s, ByteIOContext *pb, if (++(ast->sub_packet_cnt) < h) return -1; if (st->codec->codec_id == CODEC_ID_SIPR) - rm_reorder_sipr_data(ast); + ff_rm_reorder_sipr_data(ast->pkt.data, h, w); ast->sub_packet_cnt = 0; rm->audio_stream_num = st->index; @@ -787,7 +771,7 @@ ff_rm_parse_packet (AVFormatContext *s, ByteIOContext *pb, pkt->stream_index = st->index; #if 0 - if (st->codec->codec_type == CODEC_TYPE_VIDEO) { + if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { if(st->codec->codec_id == CODEC_ID_RV20){ int seq= 128*(pkt->data[2]&0x7F) + (pkt->data[3]>>1); av_log(s, AV_LOG_DEBUG, "%d %"PRId64" %d\n", *timestamp, *timestamp*512LL/25, seq); @@ -801,9 +785,9 @@ ff_rm_parse_packet (AVFormatContext *s, ByteIOContext *pb, pkt->pts= timestamp; if (flags & 2) - pkt->flags |= PKT_FLAG_KEY; + pkt->flags |= AV_PKT_FLAG_KEY; - return st->codec->codec_type == CODEC_TYPE_AUDIO ? rm->audio_pkt_cnt : 0; + return st->codec->codec_type == AVMEDIA_TYPE_AUDIO ? rm->audio_pkt_cnt : 0; } int @@ -825,7 +809,7 @@ ff_rm_retrieve_cache (AVFormatContext *s, ByteIOContext *pb, rm->audio_pkt_cnt--; if ((pkt->pts = ast->audiotimestamp) != AV_NOPTS_VALUE) { ast->audiotimestamp = AV_NOPTS_VALUE; - pkt->flags = PKT_FLAG_KEY; + pkt->flags = AV_PKT_FLAG_KEY; } else pkt->flags = 0; pkt->stream_index = st->index; @@ -846,6 +830,7 @@ static int rm_read_packet(AVFormatContext *s, AVPacket *pkt) // If there are queued audio packet return them first st = s->streams[rm->audio_stream_num]; ff_rm_retrieve_cache(s, s->pb, st, st->priv_data, pkt); + flags = 0; } else { if (rm->old_format) { RMStream *ast; @@ -856,6 +841,7 @@ static int rm_read_packet(AVFormatContext *s, AVPacket *pkt) len = !ast->audio_framesize ? RAW_PACKET_SIZE : ast->coded_framesize * ast->sub_packet_h / 2; flags = (seq++ == 1) ? 2 : 0; + pos = url_ftell(s->pb); } else { len=sync(s, ×tamp, &flags, &i, &pos); if (len > 0) @@ -929,7 +915,7 @@ static int64_t rm_read_dts(AVFormatContext *s, int stream_index, return AV_NOPTS_VALUE; st = s->streams[stream_index2]; - if (st->codec->codec_type == CODEC_TYPE_VIDEO) { + if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { h= get_byte(s->pb); len--; if(!(h & 0x40)){ seq = get_byte(s->pb); len--;