Ticket #364: rmdec.diff

File rmdec.diff, 13.8 KB (added by roytam1, 5 years ago)

rm timestamp workaround patch for libavformat

  • libavformat/rmdec.c

    diff --git a/libavformat/rmdec.c b/libavformat/rmdec.c
    index d952391..baff50d 100644
    a b typedef struct { 
    4848    int remaining_len; 
    4949    int audio_stream_num; ///< Stream number for audio packets 
    5050    int audio_pkt_cnt; ///< Output packet counter 
     51 
     52    int video_after_seek; 
     53    int64_t kf_base;    ///< timestamp of the prev. video keyframe 
     54    uint32_t kf_pts;    ///< timestamp of next video keyframe 
    5155} RMDemuxContext; 
    5256 
    5357static const unsigned char sipr_swaps[38][2] = { 
    static const unsigned char sipr_swaps[38][2] = { 
    6569 
    6670const unsigned char ff_sipr_subpk_size[4] = { 29, 19, 37, 20 }; 
    6771 
     72#define RM_SKIP_BITS(n) buffer<<=n 
     73#define RM_SHOW_BITS(n) ((buffer)>>(32-(n))) 
     74 
     75static int rm_fix_timestamp(uint8_t *buf, uint32_t timestamp, uint32_t format, 
     76    int64_t *kf_base, int *kf_pts, int *pts) 
     77{ 
     78    uint8_t *s = buf + 1 + (*buf+1)*8; 
     79    uint32_t buffer = (s[0]<<24) + (s[1]<<16) + (s[2]<<8) + s[3]; 
     80    uint32_t kf = timestamp; 
     81    int pict_type; 
     82    uint32_t orig_kf; 
     83 
     84    if(format == MKTAG('R','V','3','0') || format == MKTAG('R','V','4','0')){ 
     85        if(format == MKTAG('R','V','3','0')){ 
     86            RM_SKIP_BITS(3); 
     87            pict_type = RM_SHOW_BITS(2); 
     88            RM_SKIP_BITS(2 + 7); 
     89        }else{ 
     90            RM_SKIP_BITS(1); 
     91            pict_type = RM_SHOW_BITS(2); 
     92            RM_SKIP_BITS(2 + 7 + 3); 
     93        } 
     94        orig_kf = kf = RM_SHOW_BITS(13);  //    kf= 2*SHOW_BITS(12); 
     95        if(pict_type <= 1){ 
     96            // I frame, sync timestamps: 
     97            *kf_base = (int64_t)timestamp-kf; 
     98            av_log(NULL, AV_LOG_DEBUG,"\nTS: base=%08"PRIX64"\n",*kf_base); 
     99            kf = timestamp; 
     100        } else { 
     101            // P/B frame, merge timestamps: 
     102            int64_t tmp = (int64_t)timestamp - *kf_base; 
     103            kf |= tmp&(~0x1fff);    // combine with packet timestamp 
     104            if(kf<tmp-4096) kf += 8192; else // workaround wrap-around problems 
     105            if(kf>tmp+4096) kf -= 8192; 
     106            kf += *kf_base; 
     107        } 
     108        if(pict_type != 3){ // P || I  frame -> swap timestamps 
     109            uint32_t tmp=kf; 
     110            kf = *kf_pts; 
     111            *kf_pts = tmp; 
     112        } 
     113        av_log(NULL, AV_LOG_DEBUG,"\nTS: %08X -> %08X (%04X) %d %02X %02X %02X %02X %5u\n", 
     114            timestamp,kf,orig_kf,pict_type,s[0],s[1],s[2],s[3],pts?kf-(*pts):0); 
     115    } 
     116    if(pts) 
     117         *pts = kf; 
     118    return kf; 
     119} 
     120 
     121static void process_video_timestamp(RMDemuxContext *rm, uint32_t codec_tag,AVPacket *pkt) 
     122{ 
     123    //FIXME: it seems that only RV30 can deliver the braindamaged AV_NOPTS_VALUE 
     124    if(pkt->pts == AV_NOPTS_VALUE) 
     125        return; 
     126    if(rm->video_after_seek){ 
     127        rm->kf_base = 0; 
     128        rm->kf_pts = pkt->pts; 
     129        rm->video_after_seek = 0; 
     130    } 
     131    pkt->pts = rm_fix_timestamp(pkt->data, pkt->pts, 
     132                                     codec_tag, 
     133                                     &rm->kf_base, &rm->kf_pts, 
     134                                     NULL); 
     135} 
     136 
    68137static inline void get_strl(AVIOContext *pb, char *buf, int buf_size, int len) 
    69138{ 
    70139    int i; 
    71     char *q, r; 
     140    char *q = buf, r; 
    72141 
    73142    q = buf; 
    74143    for(i=0;i<len;i++) { 
    static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb, 
    125194                                     AVStream *st, RMStream *ast, int read_all) 
    126195{ 
    127196    char buf[256]; 
    128     uint32_t version; 
     197    uint32_t version,headsize; 
    129198    int ret; 
    130199 
    131200    /* ra type header */ 
    132201    version = avio_rb16(pb); /* version */ 
     202    headsize = avio_rb16(pb); 
    133203    if (version == 3) { 
    134         int header_size = avio_rb16(pb); 
    135204        int64_t startpos = avio_tell(pb); 
     205        int64_t headoffset = startpos + headsize; 
     206 
    136207        avio_skip(pb, 14); 
    137208        rm_read_metadata(s, 0); 
    138         if ((startpos + header_size) >= avio_tell(pb) + 2) { 
     209        if (headoffset >= avio_tell(pb) + 2) { 
    139210            // fourcc (should always be "lpcJ") 
    140211            avio_r8(pb); 
    141212            get_str8(pb, buf, sizeof(buf)); 
    142213        } 
    143214        // Skip extra header crap (this should never happen) 
    144         if ((startpos + header_size) > avio_tell(pb)) 
    145             avio_skip(pb, header_size + startpos - avio_tell(pb)); 
     215        if (headoffset > avio_tell(pb)) 
     216            avio_skip(pb, headoffset - avio_tell(pb)); 
    146217        st->codec->sample_rate = 8000; 
    147218        st->codec->channels = 1; 
    148219        st->codec->codec_type = AVMEDIA_TYPE_AUDIO; 
    149220        st->codec->codec_id = CODEC_ID_RA_144; 
    150221    } else { 
    151         int flavor, sub_packet_h, coded_framesize, sub_packet_size; 
     222        int flavor; 
    152223        int codecdata_length; 
    153224        /* old version (4) */ 
    154         avio_skip(pb, 2); /* unused */ 
    155225        avio_rb32(pb); /* .ra4 */ 
    156226        avio_rb32(pb); /* data size */ 
    157227        avio_rb16(pb); /* version2 */ 
    158228        avio_rb32(pb); /* header size */ 
    159229        flavor= avio_rb16(pb); /* add codec info / flavor */ 
    160         ast->coded_framesize = coded_framesize = avio_rb32(pb); /* coded frame size */ 
     230        ast->coded_framesize = avio_rb32(pb); /* coded frame size */ 
    161231        avio_rb32(pb); /* ??? */ 
    162232        avio_rb32(pb); /* ??? */ 
    163233        avio_rb32(pb); /* ??? */ 
    164         ast->sub_packet_h = sub_packet_h = avio_rb16(pb); /* 1 */ 
     234        ast->sub_packet_h = avio_rb16(pb); /* 1 */ 
    165235        st->codec->block_align= avio_rb16(pb); /* frame size */ 
    166         ast->sub_packet_size = sub_packet_size = avio_rb16(pb); /* sub packet size */ 
     236        ast->sub_packet_size = avio_rb16(pb); /* sub packet size */ 
    167237        avio_rb16(pb); /* ??? */ 
    168238        if (version == 5) { 
    169             avio_rb16(pb); avio_rb16(pb); avio_rb16(pb); 
     239            avio_rb16(pb); 
     240            avio_rb16(pb); 
     241            avio_rb16(pb); 
    170242        } 
    171243        st->codec->sample_rate = avio_rb16(pb); 
    172         avio_rb32(pb); 
     244        avio_rb16(pb); /* ??? */ 
     245        avio_rb16(pb); /* sample size */ 
    173246        st->codec->channels = avio_rb16(pb); 
    174247        if (version == 5) { 
    175248            avio_rb32(pb); 
    static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb, 
    177250            buf[4] = 0; 
    178251        } else { 
    179252            get_str8(pb, buf, sizeof(buf)); /* desc */ 
    180             get_str8(pb, buf, sizeof(buf)); /* desc */ 
     253            get_str8(pb, buf, sizeof(buf)); /* FOURCC */ 
    181254        } 
    182255        st->codec->codec_type = AVMEDIA_TYPE_AUDIO; 
    183256        st->codec->codec_tag  = AV_RL32(buf); 
    static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb, 
    190263        case CODEC_ID_RA_288: 
    191264            st->codec->extradata_size= 0; 
    192265            ast->audio_framesize = st->codec->block_align; 
    193             st->codec->block_align = coded_framesize; 
     266            st->codec->block_align = ast->coded_framesize; 
    194267 
    195             if(ast->audio_framesize >= UINT_MAX / sub_packet_h){ 
     268            if(ast->audio_framesize >= UINT_MAX / ast->sub_packet_h){ 
    196269                av_log(s, AV_LOG_ERROR, "ast->audio_framesize * sub_packet_h too large\n"); 
    197270                return -1; 
    198271            } 
    199272 
    200             av_new_packet(&ast->pkt, ast->audio_framesize * sub_packet_h); 
     273            av_new_packet(&ast->pkt, ast->audio_framesize * ast->sub_packet_h); 
    201274            break; 
    202275        case CODEC_ID_COOK: 
    203276        case CODEC_ID_ATRAC3: 
    static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb, 
    220293                } 
    221294                st->codec->block_align = ff_sipr_subpk_size[flavor]; 
    222295            } else { 
    223                 if(sub_packet_size <= 0){ 
     296                if(ast->sub_packet_size <= 0){ 
    224297                    av_log(s, AV_LOG_ERROR, "sub_packet_size is invalid\n"); 
    225298                    return -1; 
    226299                } 
    static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb, 
    229302            if ((ret = rm_read_extradata(pb, st->codec, codecdata_length)) < 0) 
    230303                return ret; 
    231304 
    232             if(ast->audio_framesize >= UINT_MAX / sub_packet_h){ 
     305            if(ast->audio_framesize >= UINT_MAX / ast->sub_packet_h){ 
    233306                av_log(s, AV_LOG_ERROR, "rm->audio_framesize * sub_packet_h too large\n"); 
    234307                return -1; 
    235308            } 
    236309 
    237             av_new_packet(&ast->pkt, ast->audio_framesize * sub_packet_h); 
     310            av_new_packet(&ast->pkt, ast->audio_framesize * ast->sub_packet_h); 
    238311            break; 
    239312        case CODEC_ID_AAC: 
    240313            avio_rb16(pb); avio_r8(pb); 
    ff_rm_read_mdpr_codecdata (AVFormatContext *s, AVIOContext *pb, 
    281354        if (rm_read_audio_stream_info(s, pb, st, rst, 0)) 
    282355            return -1; 
    283356    } else { 
    284         int fps, fps2; 
     357        int gcd, fps; 
    285358        if (avio_rl32(pb) != MKTAG('V', 'I', 'D', 'O')) { 
    286359        fail1: 
    287360            av_log(st->codec, AV_LOG_ERROR, "Unsupported video codec\n"); 
     361            st->codec->codec_id = CODEC_ID_NONE; 
    288362            goto skip; 
    289363        } 
    290364        st->codec->codec_tag = avio_rl32(pb); 
    ff_rm_read_mdpr_codecdata (AVFormatContext *s, AVIOContext *pb, 
    296370        st->codec->width = avio_rb16(pb); 
    297371        st->codec->height = avio_rb16(pb); 
    298372        st->codec->time_base.num= 1 << 16; 
    299         fps= avio_rb16(pb); 
     373        avio_rb16(pb); /* bpp */ 
    300374        st->codec->codec_type = AVMEDIA_TYPE_VIDEO; 
    301375        avio_rb32(pb); 
    302         fps2= avio_rb32(pb); 
     376        fps= avio_rb32(pb); 
    303377 
    304378        if ((ret = rm_read_extradata(pb, st->codec, codec_data_size - (avio_tell(pb) - codec_pos))) < 0) 
    305379            return ret; 
    306380 
    307381//        av_log(s, AV_LOG_DEBUG, "fps= %d fps2= %d\n", fps, fps2); 
    308         st->codec->time_base.den = fps2; 
     382        st->codec->time_base.den = fps; 
     383        gcd = av_gcd(st->codec->time_base.num, st->codec->time_base.den); 
     384        st->codec->time_base.num /= gcd; 
     385        st->codec->time_base.den /= gcd; 
    309386        //XXX: do we really need that? 
    310387        switch(st->codec->extradata[4]>>4){ 
    311388        case 1: st->codec->codec_id = CODEC_ID_RV10; break; 
    skip: 
    370447    return 0; 
    371448} 
    372449 
     450/* audio data is CBR */ 
    373451static int rm_read_header_old(AVFormatContext *s, AVFormatParameters *ap) 
    374452{ 
    375453    RMDemuxContext *rm = s->priv_data; 
    static int rm_read_header(AVFormatContext *s, AVFormatParameters *ap) 
    388466    RMDemuxContext *rm = s->priv_data; 
    389467    AVStream *st; 
    390468    AVIOContext *pb = s->pb; 
    391     unsigned int tag; 
     469    unsigned int tag, head_size; 
    392470    int tag_size; 
    393     unsigned int start_time, duration; 
    394471    unsigned int data_off = 0, indx_off = 0; 
    395472    char buf[128]; 
    396473    int flags = 0; 
    static int rm_read_header(AVFormatContext *s, AVFormatParameters *ap) 
    403480        return AVERROR(EIO); 
    404481    } 
    405482 
    406     avio_rb32(pb); /* header size */ 
    407     avio_rb16(pb); 
    408     avio_rb32(pb); 
     483    head_size = avio_rb32(pb); /* header size */ 
     484    avio_rb16(pb); /* chunk version */ 
     485    /* file version */ 
     486    if(0x12 == head_size) 
     487        avio_rb32(pb); 
     488    else 
     489        avio_rb16(pb); 
    409490    avio_rb32(pb); /* number of headers */ 
    410491 
    411492    for(;;) { 
    static int rm_read_header(AVFormatContext *s, AVFormatParameters *ap) 
    413494            return -1; 
    414495        tag = avio_rl32(pb); 
    415496        tag_size = avio_rb32(pb); 
    416         avio_rb16(pb); 
     497        avio_rb16(pb); /* version */ 
    417498#if 0 
    418499        printf("tag=%c%c%c%c (%08x) size=%d\n", 
    419500               (tag) & 0xff, 
    static int rm_read_header(AVFormatContext *s, AVFormatParameters *ap) 
    433514            avio_rb32(pb); /* max packet size */ 
    434515            avio_rb32(pb); /* avg packet size */ 
    435516            avio_rb32(pb); /* nb packets */ 
    436             avio_rb32(pb); /* duration */ 
    437             avio_rb32(pb); /* preroll */ 
    438             indx_off = avio_rb32(pb); /* index offset */ 
    439             data_off = avio_rb32(pb); /* data offset */ 
     517            avio_rb32(pb); /* duration in ms */ 
     518            avio_rb32(pb); /* preroll in ms */ 
     519            indx_off = avio_rb32(pb); /* the first index offset */ 
     520            data_off = avio_rb32(pb); /* the first data offset */ 
    440521            avio_rb16(pb); /* nb streams */ 
    441522            flags = avio_rb16(pb); /* flags */ 
    442523            break; 
    static int rm_read_header(AVFormatContext *s, AVFormatParameters *ap) 
    449530                return AVERROR(ENOMEM); 
    450531            st->id = avio_rb16(pb); 
    451532            avio_rb32(pb); /* max bit rate */ 
    452             st->codec->bit_rate = avio_rb32(pb); /* bit rate */ 
     533            st->codec->bit_rate = avio_rb32(pb); /* avg bit rate */ 
    453534            avio_rb32(pb); /* max packet size */ 
    454535            avio_rb32(pb); /* avg packet size */ 
    455             start_time = avio_rb32(pb); /* start time */ 
    456             avio_rb32(pb); /* preroll */ 
    457             duration = avio_rb32(pb); /* duration */ 
    458             st->start_time = start_time; 
    459             st->duration = duration; 
     536            st->start_time = avio_rb32(pb); /* start time in ms */ 
     537            avio_rb32(pb); /* preroll in ms */ 
     538            st->duration = avio_rb32(pb); /* duration in ms */ 
    460539            get_str8(pb, buf, sizeof(buf)); /* desc */ 
    461540            get_str8(pb, buf, sizeof(buf)); /* mimetype */ 
    462541            st->codec->codec_type = AVMEDIA_TYPE_DATA; 
    ff_rm_parse_packet (AVFormatContext *s, AVIOContext *pb, 
    786865    pkt->pts= timestamp; 
    787866    if (flags & 2) 
    788867        pkt->flags |= AV_PKT_FLAG_KEY; 
     868    if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO) 
     869        process_video_timestamp(rm,st->codec->codec_tag,pkt); 
    789870 
    790871    return st->codec->codec_type == AVMEDIA_TYPE_AUDIO ? rm->audio_pkt_cnt : 0; 
    791872} 
    ff_rm_retrieve_cache (AVFormatContext *s, AVIOContext *pb, 
    809890    rm->audio_pkt_cnt--; 
    810891    if ((pkt->pts = ast->audiotimestamp) != AV_NOPTS_VALUE) { 
    811892        ast->audiotimestamp = AV_NOPTS_VALUE; 
    812         pkt->flags = AV_PKT_FLAG_KEY; 
     893        pkt->flags |= AV_PKT_FLAG_KEY; 
    813894    } else 
    814         pkt->flags = 0; 
     895        pkt->flags &= (~AV_PKT_FLAG_KEY); 
    815896    pkt->stream_index = st->index; 
    816897 
    817898    return rm->audio_pkt_cnt; 
    static int64_t rm_read_dts(AVFormatContext *s, int stream_index, 
    9341015        avio_skip(s->pb, len); 
    9351016    } 
    9361017    *ppos = pos; 
     1018    rm->video_after_seek = 1; 
    9371019    return dts; 
    9381020} 
    9391021