Revision db7f1f95 libav/mpeg.c

View differences:

libav/mpeg.c
1 1
/*
2
 * Output a MPEG1 multiplexed video/audio stream
3
 * Copyright (c) 2000 Gerard Lantau.
2
 * MPEG1 mux/demux
3
 * Copyright (c) 2000, 2001, 2002 Gerard Lantau.
4 4
 *
5 5
 * This program is free software; you can redistribute it and/or modify
6 6
 * it under the terms of the GNU General Public License as published by
......
62 62
#define AUDIO_ID 0xc0
63 63
#define VIDEO_ID 0xe0
64 64

  
65
static int mpeg_mux_check_packet(AVFormatContext *s, int *size);
66

  
67 65
static int put_pack_header(AVFormatContext *ctx, 
68 66
                           UINT8 *buf, INT64 timestamp)
69 67
{
......
150 148

  
151 149
static int mpeg_mux_init(AVFormatContext *ctx)
152 150
{
153
    MpegMuxContext *s;
151
    MpegMuxContext *s = ctx->priv_data;
154 152
    int bitrate, i, mpa_id, mpv_id, ac3_id;
155 153
    AVStream *st;
156 154
    StreamInfo *stream;
157 155

  
158
    s = av_mallocz(sizeof(MpegMuxContext));
159
    if (!s)
160
        return -1;
161
    ctx->priv_data = s;
162 156
    s->packet_number = 0;
163 157

  
164 158
    /* XXX: hardcoded */
......
252 246
    for(i=0;i<ctx->nb_streams;i++) {
253 247
        av_free(ctx->streams[i]->priv_data);
254 248
    }
255
    av_free(s);
256 249
    return -ENOMEM;
257 250
}
258 251

  
......
409 402

  
410 403
#define MAX_SYNC_SIZE 100000
411 404

  
405
static int mpegps_probe(AVProbeData *p)
406
{
407
    int code, c, i;
408
    code = 0xff;
409

  
410
    /* we search the first start code. If it is a packet start code,
411
       then we decide it is mpeg ps. We do not send highest value to
412
       give a chance to mpegts */
413
    for(i=0;i<p->buf_size;i++) {
414
        c = p->buf[i];
415
        code = (code << 8) | c;
416
        if ((code & 0xffffff00) == 0x100) {
417
            if (code == PACK_START_CODE ||
418
                code == SYSTEM_HEADER_START_CODE ||
419
                (code >= 0x1e0 && code <= 0x1ef) ||
420
                (code >= 0x1c0 && code <= 0x1df) ||
421
                code == PRIVATE_STREAM_2 ||
422
                code == PROGRAM_STREAM_MAP ||
423
                code == PRIVATE_STREAM_1 ||
424
                code == PADDING_STREAM)
425
                return AVPROBE_SCORE_MAX - 1;
426
            else
427
                return 0;
428
        }
429
    }
430
    return 0;
431
}
432

  
433

  
412 434
typedef struct MpegDemuxContext {
413 435
    int header_state;
414
    int mux_rate; /* 50 byte/s unit */
415 436
} MpegDemuxContext;
416 437

  
417 438
static int find_start_code(ByteIOContext *pb, int *size_ptr, 
......
441 462
    return val;
442 463
}
443 464

  
444
static int check_stream_id(AVFormatContext *s, int c_id)
445
{
446
    AVStream *st;
447
    int i;
448
    
449
    for(i = 0;i < s->nb_streams;i++) {
450
        st = s->streams[i];
451
        if (st && st->id == c_id)
452
            return 1;
453
    }
454
    return 0;   
455
}
456

  
457
static int mpeg_mux_read_header(AVFormatContext *s,
458
                                AVFormatParameters *ap)
465
static int mpegps_read_header(AVFormatContext *s,
466
                                  AVFormatParameters *ap)
459 467
{
460
    MpegDemuxContext *m;
461
    int size, startcode, c, rate_bound, audio_bound, video_bound, mux_rate, val;
462
    int codec_id, n, i, type, seems_dvd;
463
    AVStream *st;
464
    offset_t start_pos;
465

  
466
    m = av_mallocz(sizeof(MpegDemuxContext));
467
    if (!m)
468
        return -ENOMEM;
469
    s->priv_data = m;
470
    seems_dvd = 0;
471
    
472
    /* search first pack header */
468
    MpegDemuxContext *m = s->priv_data;
473 469
    m->header_state = 0xff;
474
    size = MAX_SYNC_SIZE;
475
    start_pos = url_ftell(&s->pb); /* remember this pos */
476
    for(;;) {
477
        /*while (size > 0) {
478
            startcode = find_start_code(&s->pb, &size, &m->header_state);
479
            if (startcode == PACK_START_CODE)
480
                goto found;
481
        }*/
482
        /* System Header not found find streams searching through file */
483
        //fprintf(stderr,"libav: MPEG-PS System Header not found!\n");
484
        url_fseek(&s->pb, start_pos, SEEK_SET);
485
        video_bound = 0;
486
        audio_bound = 0;
487
        c = 0;
488
        s->nb_streams = 0;
489
        //size = 15*MAX_SYNC_SIZE;
490
        while (size > 0) {
491
            type = 0;
492
            codec_id = 0;
493
            n = 0;
494
            startcode = find_start_code(&s->pb, &size, &m->header_state);
495
            //fprintf(stderr,"\nstartcode: %x pos=0x%Lx\n", startcode, url_ftell(&s->pb));
496
            if (startcode == 0x1bd) {
497
                url_fseek(&s->pb, -4, SEEK_CUR);
498
                size += 4;
499
                startcode = mpeg_mux_check_packet(s, &size);
500
                //fprintf(stderr,"\nstartcode: %x pos=0x%Lx\n", startcode, url_ftell(&s->pb));
501
                if (startcode >= 0x80 && startcode <= 0x9f && !check_stream_id(s, startcode)) {
502
                    //fprintf(stderr,"Found AC3 stream ID: 0x%x\n", startcode);
503
                    type = CODEC_TYPE_AUDIO;
504
                    codec_id = CODEC_ID_AC3;
505
                    audio_bound++;
506
                    n = 1;
507
                    c = startcode;
508
                    seems_dvd = 1;
509
                }    
510
            } else if (startcode == 0x1e0 && !check_stream_id(s, startcode)) {
511
                //fprintf(stderr,"Found MPEGVIDEO stream ID: 0x%x\n", startcode);
512
                type = CODEC_TYPE_VIDEO;
513
                codec_id = CODEC_ID_MPEG1VIDEO;
514
                n = 1;
515
                c = startcode;
516
                video_bound++;
517
            } else if (startcode >= 0x1c0 && startcode <= 0x1df && !seems_dvd && !check_stream_id(s, startcode)) {
518
                //fprintf(stderr,"Found MPEGAUDIO stream ID: 0x%x\n", startcode);
519
                type = CODEC_TYPE_AUDIO;
520
                codec_id = CODEC_ID_MP2;
521
                n = 1;
522
                c = startcode;
523
                audio_bound++;
524
            } 
525
            for(i=0;i<n;i++) {
526
                st = av_mallocz(sizeof(AVStream));
527
                if (!st)
528
                    return -ENOMEM;
529
                s->streams[s->nb_streams++] = st;
530
                st->id = c;
531
                st->codec.codec_type = type;
532
                st->codec.codec_id = codec_id;
533
            }
534
        }
535
        if (video_bound || audio_bound) {
536
            url_fseek(&s->pb, start_pos, SEEK_SET);
537
            return 0;
538
        } else
539
            return -ENODATA;
540
    found:
541
        /* search system header just after pack header */
542
        /* parse pack header */
543
        get_byte(&s->pb); /* ts1 */
544
        get_be16(&s->pb); /* ts2 */
545
        get_be16(&s->pb); /* ts3 */
546

  
547
        mux_rate = get_byte(&s->pb) << 16; 
548
        mux_rate |= get_byte(&s->pb) << 8;
549
        mux_rate |= get_byte(&s->pb);
550
        mux_rate &= (1 << 22) - 1;
551
        m->mux_rate = mux_rate;
552

  
553
        startcode = find_start_code(&s->pb, &size, &m->header_state);
554
        if (startcode == SYSTEM_HEADER_START_CODE)
555
            break;
556
    }
557
    size = get_be16(&s->pb);
558
    rate_bound = get_byte(&s->pb) << 16;
559
    rate_bound |= get_byte(&s->pb) << 8;
560
    rate_bound |= get_byte(&s->pb);
561
    rate_bound = (rate_bound >> 1) & ((1 << 22) - 1);
562
    audio_bound = get_byte(&s->pb) >> 2;
563
    video_bound = get_byte(&s->pb) & 0x1f;
564
    get_byte(&s->pb); /* reserved byte */
565
#if 0
566
    printf("mux_rate=%d kbit/s\n", (m->mux_rate * 50 * 8) / 1000);
567
    printf("rate_bound=%d\n", rate_bound);
568
    printf("audio_bound=%d\n", audio_bound);
569
    printf("video_bound=%d\n", video_bound);
570
#endif
571
    size -= 6;
572
    s->nb_streams = 0;
573
    while (size > 0) {
574
        c = get_byte(&s->pb);
575
        size--;
576
        if ((c & 0x80) == 0)
577
            break;
578
        val = get_be16(&s->pb);
579
        size -= 2;
580
        if (c >= 0xc0 && c <= 0xdf) {
581
            /* mpeg audio stream */
582
            type = CODEC_TYPE_AUDIO;
583
            codec_id = CODEC_ID_MP2;
584
            n = 1;
585
            c = c | 0x100;
586
        } else if (c >= 0xe0 && c <= 0xef) {
587
            type = CODEC_TYPE_VIDEO;
588
            codec_id = CODEC_ID_MPEG1VIDEO;
589
            n = 1;
590
            c = c | 0x100;
591
        } else if (c == 0xb8) {
592
            /* all audio streams */
593
            /* XXX: hack for DVD: we force AC3, although we do not
594
               know that this codec will be used */
595
            type = CODEC_TYPE_AUDIO;
596
            codec_id = CODEC_ID_AC3;
597
            /* XXX: Another hack for DVD: it seems, that AC3 streams
598
               aren't signaled on audio_bound on some DVDs (Matrix) */
599
            if (audio_bound == 0)
600
            	audio_bound++;
601
            n = audio_bound;
602
            c = 0x80;
603
            //c = 0x1c0;
604
        } else if (c == 0xb9) {
605
            /* all video streams */
606
            type = CODEC_TYPE_VIDEO;
607
            codec_id = CODEC_ID_MPEG1VIDEO;
608
            n = video_bound;
609
            c = 0x1e0;
610
        } else {
611
            type = 0;
612
            codec_id = 0;
613
            n = 0;
614
        }
615
        for(i=0;i<n;i++) {
616
            st = av_mallocz(sizeof(AVStream));
617
            if (!st)
618
                return -ENOMEM;
619
            s->streams[s->nb_streams++] = st;
620
            st->id = c + i;
621
            st->codec.codec_type = type;
622
            st->codec.codec_id = codec_id;
623
        }
624
    }
625

  
470
    /* no need to do more */
626 471
    return 0;
627 472
}
628 473

  
......
641 486
    return pts;
642 487
}
643 488

  
644
static int mpeg_mux_read_packet(AVFormatContext *s,
645
                                AVPacket *pkt)
489
static int mpegps_read_packet(AVFormatContext *s,
490
                                  AVPacket *pkt)
646 491
{
647 492
    MpegDemuxContext *m = s->priv_data;
648 493
    AVStream *st;
649
    int len, size, startcode, i, c, flags, header_len;
494
    int len, size, startcode, i, c, flags, header_len, type, codec_id;
650 495
    INT64 pts, dts;
651 496

  
652 497
    /* next start code (should be immediately after */
......
745 590
        if (st->id == startcode)
746 591
            goto found;
747 592
    }
748
    /* skip packet */
749
    url_fskip(&s->pb, len);
750
    goto redo;
593
    /* no stream found: add a new stream */
594
    st = av_new_stream(s, startcode);
595
    if (!st) 
596
        goto skip;
597
    if (startcode >= 0x1e0 && startcode <= 0x1ef) {
598
        type = CODEC_TYPE_VIDEO;
599
        codec_id = CODEC_ID_MPEG1VIDEO;
600
    } else if (startcode >= 0x1c0 && startcode <= 0x1df) {
601
        type = CODEC_TYPE_AUDIO;
602
        codec_id = CODEC_ID_MP2;
603
    } else if (startcode >= 0x80 && startcode <= 0x9f) {
604
        type = CODEC_TYPE_AUDIO;
605
        codec_id = CODEC_ID_AC3;
606
    } else {
607
    skip:
608
        /* skip packet */
609
        url_fskip(&s->pb, len);
610
        goto redo;
611
    }
612
    st->codec.codec_type = type;
613
    st->codec.codec_id = codec_id;
751 614
 found:
752 615
    av_new_packet(pkt, len);
753 616
    //printf("\nRead Packet ID: %x PTS: %f Size: %d", startcode,
754 617
    //       (float)pts/90000, len);
755 618
    get_buffer(&s->pb, pkt->data, pkt->size);
756 619
    pkt->pts = pts;
757
    pkt->stream_index = i;
620
    pkt->stream_index = st->index;
758 621
    return 0;
759 622
}
760 623

  
761
static int mpeg_mux_check_packet(AVFormatContext *s, int *size)
762
{
763
    MpegDemuxContext *m = s->priv_data;
764
    int len, startcode, c, n, flags, header_len;
765
    INT64 pts, dts;
766

  
767
    /* next start code (should be immediately after */
768
 redo:
769
    m->header_state = 0xff;
770
    startcode = find_start_code(&s->pb, size, &m->header_state);
771
    
772
    if (startcode < 0)
773
        return -EIO;
774
    if (startcode == PACK_START_CODE)
775
        goto redo;
776
    if (startcode == SYSTEM_HEADER_START_CODE)
777
        goto redo;
778
    if (startcode == PADDING_STREAM ||
779
        startcode == PRIVATE_STREAM_2) {
780
        /* skip them */
781
        len = get_be16(&s->pb);
782
        url_fskip(&s->pb, len);
783
        goto redo;
784
    }
785
    /* find matching stream */
786
    if (!((startcode >= 0x1c0 && startcode <= 0x1df) ||
787
          (startcode >= 0x1e0 && startcode <= 0x1ef) ||
788
          (startcode == 0x1bd)))
789
        goto redo;
790

  
791
    n = *size;
792
    len = get_be16(&s->pb);
793
    n -= 2;
794
    pts = 0;
795
    dts = 0;
796
    /* stuffing */
797
    for(;;) {
798
        c = get_byte(&s->pb);
799
        len--;
800
        n--;
801
        /* XXX: for mpeg1, should test only bit 7 */
802
        if (c != 0xff) 
803
            break;
804
    }
805
    if ((c & 0xc0) == 0x40) {
806
        /* buffer scale & size */
807
        get_byte(&s->pb);
808
        c = get_byte(&s->pb);
809
        len -= 2;
810
        n -= 2;
811
    }
812
    if ((c & 0xf0) == 0x20) {
813
        pts = get_pts(&s->pb, c);
814
        len -= 4;
815
        n -= 4;
816
        dts = pts;
817
    } else if ((c & 0xf0) == 0x30) {
818
        pts = get_pts(&s->pb, c);
819
        dts = get_pts(&s->pb, -1);
820
        len -= 9;
821
        n -= 9;
822
    } else if ((c & 0xc0) == 0x80) {
823
        /* mpeg 2 PES */
824
        if ((c & 0x30) != 0) {
825
            fprintf(stderr, "Encrypted multiplex not handled\n");
826
            return -EIO;
827
        }
828
        flags = get_byte(&s->pb);
829
        header_len = get_byte(&s->pb);
830
        len -= 2;
831
        n -= 2;
832
        if (header_len > len)
833
            goto redo;
834
        if ((flags & 0xc0) == 0x40) {
835
            pts = get_pts(&s->pb, -1);
836
            dts = pts;
837
            header_len -= 5;
838
            len -= 5;
839
            n -= 5;
840
        } if ((flags & 0xc0) == 0xc0) {
841
            pts = get_pts(&s->pb, -1);
842
            dts = get_pts(&s->pb, -1);
843
            header_len -= 10;
844
            len -= 10;
845
            n -= 10;
846
        }
847
        len -= header_len;
848
        n -= header_len;
849
        while (header_len > 0) {
850
            get_byte(&s->pb);
851
            header_len--;
852
        }
853
    }
854
    if (startcode == 0x1bd) {
855
        startcode = get_byte(&s->pb);
856
        len--;
857
        n--;
858
        if (startcode >= 0x80 && startcode <= 0xbf) {
859
            /* audio: skip header */
860
            get_byte(&s->pb);
861
            get_byte(&s->pb);
862
            get_byte(&s->pb);
863
            len -= 3;
864
            n -= 3;
865
        }
866
    }
867
    *size = n;
868
    return startcode;
869
}
870

  
871

  
872
static int mpeg_mux_read_close(AVFormatContext *s)
624
static int mpegps_read_close(AVFormatContext *s)
873 625
{
874
    MpegDemuxContext *m = s->priv_data;
875
    av_free(m);
876 626
    return 0;
877 627
}
878 628

  
879
AVFormat mpeg_mux_format = {
629
static AVOutputFormat mpegps_mux = {
880 630
    "mpeg",
881
    "MPEG multiplex format",
631
    "MPEG PS format",
882 632
    "video/x-mpeg",
883 633
    "mpg,mpeg,vob",
634
    sizeof(MpegMuxContext),
884 635
    CODEC_ID_MP2,
885 636
    CODEC_ID_MPEG1VIDEO,
886 637
    mpeg_mux_init,
887 638
    mpeg_mux_write_packet,
888 639
    mpeg_mux_end,
640
};
889 641

  
890
    mpeg_mux_read_header,
891
    mpeg_mux_read_packet,
892
    mpeg_mux_read_close,
642
static AVInputFormat mpegps_demux = {
643
    "mpeg",
644
    "MPEG PS format",
645
    sizeof(MpegDemuxContext),
646
    mpegps_probe,
647
    mpegps_read_header,
648
    mpegps_read_packet,
649
    mpegps_read_close,
650
    flags: AVFMT_NOHEADER,
893 651
};
652

  
653
int mpegps_init(void)
654
{
655
    av_register_output_format(&mpegps_mux);
656
    av_register_input_format(&mpegps_demux);
657
    return 0;
658
}

Also available in: Unified diff