comparison rmdec.c @ 2653:67667d13bab5 libavformat

Demux full frames instead of sliced for RealVideo. Some changes by Roberto Togni and blessed by him on IRC.
author kostya
date Sun, 21 Oct 2007 17:17:28 +0000
parents ecd8a9aa182d
children 997fb1ac4783
comparison
equal deleted inserted replaced
2652:2d28b2a5b2e4 2653:67667d13bab5
348 header_end: 348 header_end:
349 rm->nb_packets = get_be32(pb); /* number of packets */ 349 rm->nb_packets = get_be32(pb); /* number of packets */
350 if (!rm->nb_packets && (flags & 4)) 350 if (!rm->nb_packets && (flags & 4))
351 rm->nb_packets = 3600 * 25; 351 rm->nb_packets = 3600 * 25;
352 get_be32(pb); /* next data header */ 352 get_be32(pb); /* next data header */
353 rm->curpic_num = -1;
353 return 0; 354 return 0;
354 355
355 fail: 356 fail:
356 for(i=0;i<s->nb_streams;i++) { 357 for(i=0;i<s->nb_streams;i++) {
357 av_free(s->streams[i]); 358 av_free(s->streams[i]);
363 { 364 {
364 int n, n1; 365 int n, n1;
365 366
366 n = get_be16(pb); 367 n = get_be16(pb);
367 (*len)-=2; 368 (*len)-=2;
369 n &= 0x7FFF;
368 if (n >= 0x4000) { 370 if (n >= 0x4000) {
369 return n - 0x4000; 371 return n - 0x4000;
370 } else { 372 } else {
371 n1 = get_be16(pb); 373 n1 = get_be16(pb);
372 (*len)-=2; 374 (*len)-=2;
429 *stream_index= i; 431 *stream_index= i;
430 432
431 return len; 433 return len;
432 } 434 }
433 return -1; 435 return -1;
436 }
437
438 static int rm_assemble_video_frame(AVFormatContext *s, RMContext *rm, AVPacket *pkt, int len)
439 {
440 ByteIOContext *pb = &s->pb;
441 int hdr, seq, pic_num, len2, pos;
442 int type;
443 int ssize;
444
445 hdr = get_byte(pb); len--;
446 type = hdr >> 6;
447 switch(type){
448 case 0: // slice
449 case 2: // last slice
450 seq = get_byte(pb); len--;
451 len2 = get_num(pb, &len);
452 pos = get_num(pb, &len);
453 pic_num = get_byte(pb); len--;
454 rm->remaining_len = len;
455 break;
456 case 1: //whole frame
457 seq = get_byte(pb); len--;
458 if(av_new_packet(pkt, len + 9) < 0)
459 return AVERROR(EIO);
460 pkt->data[0] = 0;
461 AV_WL32(pkt->data + 1, 1);
462 AV_WL32(pkt->data + 5, 0);
463 get_buffer(pb, pkt->data + 9, len);
464 rm->remaining_len = 0;
465 return 0;
466 case 3: //frame as a part of packet
467 len2 = get_num(pb, &len);
468 pos = get_num(pb, &len);
469 pic_num = get_byte(pb); len--;
470 rm->remaining_len = len - len2;
471 if(av_new_packet(pkt, len2 + 9) < 0)
472 return AVERROR(EIO);
473 pkt->data[0] = 0;
474 AV_WL32(pkt->data + 1, 1);
475 AV_WL32(pkt->data + 5, 0);
476 get_buffer(pb, pkt->data + 9, len2);
477 return 0;
478 }
479 //now we have to deal with single slice
480
481 if((seq & 0x7F) == 1 || rm->curpic_num != pic_num){
482 rm->slices = ((hdr & 0x3F) << 1) + 1;
483 ssize = len2 + 8*rm->slices + 1;
484 rm->videobuf = av_realloc(rm->videobuf, ssize);
485 rm->videobufsize = ssize;
486 rm->videobufpos = 8*rm->slices + 1;
487 rm->cur_slice = 0;
488 rm->curpic_num = pic_num;
489 }
490 if(type == 2){
491 len = FFMIN(len, pos);
492 pos = len2 - pos;
493 }
494
495 if(++rm->cur_slice > rm->cur_slice)
496 return 1;
497 AV_WL32(rm->videobuf - 7 + 8*rm->cur_slice, 1);
498 AV_WL32(rm->videobuf - 3 + 8*rm->cur_slice, rm->videobufpos - 8*rm->slices - 1);
499 if(rm->videobufpos + len > rm->videobufsize)
500 return 1;
501 if (get_buffer(pb, rm->videobuf + rm->videobufpos, len) != len)
502 return AVERROR(EIO);
503 rm->videobufpos += len,
504 rm->remaining_len-= len;
505
506 if(type == 2 || (rm->videobufpos) == rm->videobufsize){
507 //adjust slice headers
508 memmove(rm->videobuf + 1 + 8*rm->cur_slice, rm->videobuf + 1 + 8*rm->slices, rm->videobufsize - 1 - 8*rm->slices);
509 ssize = rm->videobufsize - 8*(rm->slices - rm->cur_slice);
510
511 rm->videobuf[0] = rm->cur_slice-1;
512 if(av_new_packet(pkt, ssize) < 0)
513 return AVERROR(ENOMEM);
514 memcpy(pkt->data, rm->videobuf, ssize);
515 return 0;
516 }
517
518 return 1;
434 } 519 }
435 520
436 static int rm_read_packet(AVFormatContext *s, AVPacket *pkt) 521 static int rm_read_packet(AVFormatContext *s, AVPacket *pkt)
437 { 522 {
438 RMContext *rm = s->priv_data; 523 RMContext *rm = s->priv_data;
490 if(len<0) 575 if(len<0)
491 return AVERROR(EIO); 576 return AVERROR(EIO);
492 st = s->streams[i]; 577 st = s->streams[i];
493 578
494 if (st->codec->codec_type == CODEC_TYPE_VIDEO) { 579 if (st->codec->codec_type == CODEC_TYPE_VIDEO) {
495 int h, pic_num, len2, pos;
496
497 h= get_byte(pb); len--;
498 if(!(h & 0x40)){
499 seq = get_byte(pb); len--;
500 }
501
502 if((h & 0xc0) == 0x40){
503 len2= pos= 0;
504 }else{
505 len2 = get_num(pb, &len);
506 pos = get_num(pb, &len);
507 }
508 /* picture number */
509 pic_num= get_byte(pb); len--;
510 rm->remaining_len= len;
511 rm->current_stream= st->id; 580 rm->current_stream= st->id;
512 581 if(rm_assemble_video_frame(s, rm, pkt, len) == 1)
513 // av_log(NULL, AV_LOG_DEBUG, "%X len:%d pos:%d len2:%d pic_num:%d\n",h, len, pos, len2, pic_num); 582 goto resync;//got partial frame
514 if((h & 0xc0) == 0x80)
515 len=pos;
516 if(len2 && len2<len)
517 len=len2;
518 rm->remaining_len-= len;
519 av_get_packet(pb, pkt, len);
520
521 } else if (st->codec->codec_type == CODEC_TYPE_AUDIO) { 583 } else if (st->codec->codec_type == CODEC_TYPE_AUDIO) {
522 if ((st->codec->codec_id == CODEC_ID_RA_288) || 584 if ((st->codec->codec_id == CODEC_ID_RA_288) ||
523 (st->codec->codec_id == CODEC_ID_COOK) || 585 (st->codec->codec_id == CODEC_ID_COOK) ||
524 (st->codec->codec_id == CODEC_ID_ATRAC3)) { 586 (st->codec->codec_id == CODEC_ID_ATRAC3)) {
525 int x; 587 int x;
618 static int rm_read_close(AVFormatContext *s) 680 static int rm_read_close(AVFormatContext *s)
619 { 681 {
620 RMContext *rm = s->priv_data; 682 RMContext *rm = s->priv_data;
621 683
622 av_free(rm->audiobuf); 684 av_free(rm->audiobuf);
685 av_free(rm->videobuf);
623 return 0; 686 return 0;
624 } 687 }
625 688
626 static int rm_probe(AVProbeData *p) 689 static int rm_probe(AVProbeData *p)
627 { 690 {