Revision 7c5934ed

View differences:

libavformat/nut.c
90 90
    int64_t packet_size_pos;
91 91
    int64_t last_frame_start[3];
92 92
    FrameCode frame_code[256];
93
    int stream_count;
93 94
    StreamContext *stream;
94 95
} NUTContext;
95 96

  
......
328 329
    return 7; //not reached
329 330
}
330 331

  
332
static uint64_t find_any_startcode(ByteIOContext *bc, int64_t pos){
333
    uint64_t state=0;
334
    
335
    if(pos >= 0)
336
        url_fseek(bc, pos, SEEK_SET); //note, this may fail if the stream isnt seekable, but that shouldnt matter, as in this case we simply start where we are currently
337

  
338
    while(bytes_left(bc)){
339
        state= (state<<8) | get_byte(bc);
340
        if((state>>56) != 'N')
341
            continue;
342
        switch(state){
343
        case MAIN_STARTCODE:
344
        case STREAM_STARTCODE:
345
        case KEYFRAME_STARTCODE:
346
        case INFO_STARTCODE:
347
        case INDEX_STARTCODE:
348
            return state;
349
        }
350
    }
351
    return 0;
352
}
353

  
354
static int find_startcode(ByteIOContext *bc, uint64_t code, int64_t pos){
355
    for(;;){
356
        uint64_t startcode= find_any_startcode(bc, pos);
357
        if(startcode == code)
358
            return 0;
359
        else if(startcode == 0)
360
            return -1;
361
        pos=-1;
362
    }
363
}
364

  
331 365
#ifdef CONFIG_ENCODERS
332 366
static int put_v(ByteIOContext *bc, uint64_t val)
333 367
{
......
763 797
    return 0;
764 798
}
765 799

  
766
static int nut_read_header(AVFormatContext *s, AVFormatParameters *ap)
767
{
768
    NUTContext *nut = s->priv_data;
800
static int decode_main_header(NUTContext *nut){
801
    AVFormatContext *s= nut->avf;
769 802
    ByteIOContext *bc = &s->pb;
770 803
    uint64_t tmp;
771
    int cur_stream, nb_streams, i, j;
772

  
773
    nut->avf= s;
804
    int i, j;
774 805
    
775
    av_set_pts_info(s, 60, 1, AV_TIME_BASE);
776

  
777
    /* main header */
778
    tmp = get_be64(bc);
779
    if (tmp != MAIN_STARTCODE)
780
	av_log(s, AV_LOG_ERROR, "damaged? startcode!=1 (%Ld)\n", tmp);
781 806
    get_packetheader(nut, bc, 8, 1);
782
    
807

  
783 808
    tmp = get_v(bc);
784
    if (tmp != 1)
809
    if (tmp != 1){
785 810
	av_log(s, AV_LOG_ERROR, "bad version (%Ld)\n", tmp);
811
        return -1;
812
    }
786 813
    
787
    nb_streams = get_v(bc);
814
    nut->stream_count = get_v(bc);
788 815
    get_v(bc); //checksum threshold
789 816

  
790 817
    for(i=0; i<256;){
......
811 838
        }
812 839

  
813 840
        for(j=0; j<count; j++,i++){
814
            if(tmp_stream > nb_streams + 1){
841
            if(tmp_stream > nut->stream_count + 1){
815 842
                av_log(s, AV_LOG_ERROR, "illegal stream number\n");
816 843
                return -1;
817 844
            }
......
830 857
        av_log(s, AV_LOG_ERROR, "illegal frame_code table\n");
831 858
        return -1;
832 859
    }
833
    
860

  
834 861
    if(check_checksum(bc)){
835 862
        av_log(s, AV_LOG_ERROR, "Main header checksum missmatch\n");
836 863
        return -1;
837 864
    }
838
    
839
    s->bit_rate = 0;
840 865

  
841
    nut->stream = av_malloc(sizeof(StreamContext)*nb_streams);
866
    return 0;
867
}
868

  
869
static int decode_stream_header(NUTContext *nut){
870
    AVFormatContext *s= nut->avf;
871
    ByteIOContext *bc = &s->pb;
872
    int class, nom, denom, stream_id, i;
873
    uint64_t tmp;
874
    AVStream *st;
875
    
876
    get_packetheader(nut, bc, 8, 1);
877
    stream_id= get_v(bc);
878
    if(stream_id >= nut->stream_count || s->streams[stream_id])
879
        return -1;
842 880
    
843
    /* stream header */
844
    for (cur_stream = 0; cur_stream < nb_streams; cur_stream++)
881
    st = av_new_stream(s, stream_id);
882
    if (!st)
883
        return AVERROR_NOMEM;
884
    class = get_v(bc);
885
    tmp = get_v(bc);
886
    switch(class)
845 887
    {
846
	int class, nom, denom;
847
	AVStream *st;
848
	
849
	tmp = get_be64(bc);
850
	if (tmp != STREAM_STARTCODE)
851
	    av_log(s, AV_LOG_ERROR, "damaged? startcode!=1 (%Ld)\n", tmp);
852
	get_packetheader(nut, bc, 8, 1);
853
	st = av_new_stream(s, get_v(bc));
854
	if (!st)
855
	    return AVERROR_NOMEM;
856
	class = get_v(bc);
857
	tmp = get_v(bc);
858
	switch(class)
859
	{
860
	    case 0:
861
		st->codec.codec_type = CODEC_TYPE_VIDEO;
862
		st->codec.codec_id = codec_get_bmp_id(tmp);
863
		if (st->codec.codec_id == CODEC_ID_NONE)
864
		    av_log(s, AV_LOG_ERROR, "Unknown codec?!\n");
865
		break;
866
	    case 32:
867
		st->codec.codec_type = CODEC_TYPE_AUDIO;
868
		st->codec.codec_id = codec_get_wav_id(tmp);
869
		if (st->codec.codec_id == CODEC_ID_NONE)
870
		    av_log(s, AV_LOG_ERROR, "Unknown codec?!\n");
871
		break;
872
	    default:
873
		av_log(s, AV_LOG_ERROR, "Unknown stream class (%d)\n", class);
874
		return -1;
875
	}
876
	s->bit_rate += get_v(bc);
877
	get_v(bc); /* language code */
878
	nom = get_v(bc);
879
	denom = get_v(bc);
880
	nut->stream[cur_stream].msb_timestamp_shift = get_v(bc);
881
	for(i=0; i<3; i++)
882
		nut->stream[cur_stream].initial_pts_predictor[i]= get_v(bc);
883
	for(i=0; i<2; i++)
884
		nut->stream[cur_stream].initial_size_predictor[i]= get_v(bc);
885
	get_byte(bc); /* flags */
886

  
887
	/* codec specific data headers */
888
	while(get_v(bc) != 0){
889
            st->codec.extradata_size= get_v(bc);
890
            st->codec.extradata= av_mallocz(st->codec.extradata_size);
891
            get_buffer(bc, st->codec.extradata, st->codec.extradata_size);            
892
//	    url_fskip(bc, get_v(bc));
893
        }
894
	
895
	if (class == 0) /* VIDEO */
896
	{
897
	    st->codec.width = get_v(bc);
898
	    st->codec.height = get_v(bc);
899
	    st->codec.sample_aspect_ratio.num= get_v(bc);
900
	    st->codec.sample_aspect_ratio.den= get_v(bc);
901
	    get_v(bc); /* csp type */
902

  
903
	    st->codec.frame_rate = nom;
904
	    st->codec.frame_rate_base = denom;
905
	}
906
	if (class == 32) /* AUDIO */
907
	{
908
	    st->codec.sample_rate = (get_v(bc) * nom) / denom;
909
	    st->codec.channels = get_v(bc);
910
	}
911
        if(check_checksum(bc)){
912
            av_log(s, AV_LOG_ERROR, "Stream header %d checksum missmatch\n", cur_stream);
888
        case 0:
889
            st->codec.codec_type = CODEC_TYPE_VIDEO;
890
            st->codec.codec_id = codec_get_bmp_id(tmp);
891
            if (st->codec.codec_id == CODEC_ID_NONE)
892
                av_log(s, AV_LOG_ERROR, "Unknown codec?!\n");
893
            break;
894
        case 32:
895
            st->codec.codec_type = CODEC_TYPE_AUDIO;
896
            st->codec.codec_id = codec_get_wav_id(tmp);
897
            if (st->codec.codec_id == CODEC_ID_NONE)
898
                av_log(s, AV_LOG_ERROR, "Unknown codec?!\n");
899
            break;
900
        default:
901
            av_log(s, AV_LOG_ERROR, "Unknown stream class (%d)\n", class);
913 902
            return -1;
914
        }
915
        nut->stream[cur_stream].rate_num= nom;
916
        nut->stream[cur_stream].rate_den= denom;
917 903
    }
918
        
919
    tmp = get_be64(bc);
920
    if (tmp == INFO_STARTCODE){
921
	get_packetheader(nut, bc, 8, 1);
904
    s->bit_rate += get_v(bc);
905
    get_v(bc); /* language code */
906
    nom = get_v(bc);
907
    denom = get_v(bc);
908
    nut->stream[stream_id].msb_timestamp_shift = get_v(bc);
909
    for(i=0; i<3; i++)
910
            nut->stream[stream_id].initial_pts_predictor[i]= get_v(bc);
911
    for(i=0; i<2; i++)
912
            nut->stream[stream_id].initial_size_predictor[i]= get_v(bc);
913
    get_byte(bc); /* flags */
914

  
915
    /* codec specific data headers */
916
    while(get_v(bc) != 0){
917
        st->codec.extradata_size= get_v(bc);
918
        st->codec.extradata= av_mallocz(st->codec.extradata_size);
919
        get_buffer(bc, st->codec.extradata, st->codec.extradata_size);            
920
//	    url_fskip(bc, get_v(bc));
921
    }
922 922
    
923
        for(;;){
924
            int id= get_v(bc);
925
            char *name, *type, custom_name[256], custom_type[256];
923
    if (class == 0) /* VIDEO */
924
    {
925
        st->codec.width = get_v(bc);
926
        st->codec.height = get_v(bc);
927
        st->codec.sample_aspect_ratio.num= get_v(bc);
928
        st->codec.sample_aspect_ratio.den= get_v(bc);
929
        get_v(bc); /* csp type */
930

  
931
        st->codec.frame_rate = nom;
932
        st->codec.frame_rate_base = denom;
933
    }
934
    if (class == 32) /* AUDIO */
935
    {
936
        st->codec.sample_rate = (get_v(bc) * nom) / denom;
937
        st->codec.channels = get_v(bc);
938
    }
939
    if(check_checksum(bc)){
940
        av_log(s, AV_LOG_ERROR, "Stream header %d checksum missmatch\n", stream_id);
941
        return -1;
942
    }
943
    nut->stream[stream_id].rate_num= nom;
944
    nut->stream[stream_id].rate_den= denom;
945
    return 0;
946
}
926 947

  
927
            if(!id)
928
                break;
929
            else if(id >= sizeof(info_table)/sizeof(info_table[0])){
930
                av_log(s, AV_LOG_ERROR, "info id is too large %d %d\n", id, sizeof(info_table)/sizeof(info_table[0]));
931
                return -1;
932
            }
948
static int decode_info_header(NUTContext *nut){
949
    AVFormatContext *s= nut->avf;
950
    ByteIOContext *bc = &s->pb;
951
    
952
    get_packetheader(nut, bc, 8, 1);
953

  
954
    for(;;){
955
        int id= get_v(bc);
956
        char *name, *type, custom_name[256], custom_type[256];
957

  
958
        if(!id)
959
            break;
960
        else if(id >= sizeof(info_table)/sizeof(info_table[0])){
961
            av_log(s, AV_LOG_ERROR, "info id is too large %d %d\n", id, sizeof(info_table)/sizeof(info_table[0]));
962
            return -1;
963
        }
933 964

  
934
            type= info_table[id][1];
935
            name= info_table[id][0];
965
        type= info_table[id][1];
966
        name= info_table[id][0];
936 967
//av_log(s, AV_LOG_DEBUG, "%d %s %s\n", id, type, name);
937 968

  
938
            if(!type){
939
                get_str(bc, custom_type, sizeof(custom_type));
940
                type= custom_type;
941
            }
942
            if(!name){
943
                get_str(bc, custom_name, sizeof(custom_name));
944
                name= custom_name;
945
            }
946
            
947
            if(!strcmp(type, "v")){
948
                int value= get_v(bc);
949
            }else{
950
                if(!strcmp(name, "Author"))
951
                    get_str(bc, s->author, sizeof(s->author));
952
                else if(!strcmp(name, "Title"))
953
                    get_str(bc, s->title, sizeof(s->title));
954
                else if(!strcmp(name, "Copyright"))
955
                    get_str(bc, s->copyright, sizeof(s->copyright));
956
                else if(!strcmp(name, "Description"))
957
                    get_str(bc, s->comment, sizeof(s->comment));
958
                else
959
                    get_str(bc, NULL, 0);
960
            }
969
        if(!type){
970
            get_str(bc, custom_type, sizeof(custom_type));
971
            type= custom_type;
972
        }
973
        if(!name){
974
            get_str(bc, custom_name, sizeof(custom_name));
975
            name= custom_name;
961 976
        }
962
        if(check_checksum(bc)){
963
            av_log(s, AV_LOG_ERROR, "Info header checksum missmatch\n");
977
        
978
        if(!strcmp(type, "v")){
979
            int value= get_v(bc);
980
        }else{
981
            if(!strcmp(name, "Author"))
982
                get_str(bc, s->author, sizeof(s->author));
983
            else if(!strcmp(name, "Title"))
984
                get_str(bc, s->title, sizeof(s->title));
985
            else if(!strcmp(name, "Copyright"))
986
                get_str(bc, s->copyright, sizeof(s->copyright));
987
            else if(!strcmp(name, "Description"))
988
                get_str(bc, s->comment, sizeof(s->comment));
989
            else
990
                get_str(bc, NULL, 0);
964 991
        }
965
    }else
966
        url_fseek(bc, -8, SEEK_CUR);
992
    }
993
    if(check_checksum(bc)){
994
        av_log(s, AV_LOG_ERROR, "Info header checksum missmatch\n");
995
        return -1;
996
    }
997
    return 0;
998
}
999

  
1000
static int nut_read_header(AVFormatContext *s, AVFormatParameters *ap)
1001
{
1002
    NUTContext *nut = s->priv_data;
1003
    ByteIOContext *bc = &s->pb;
1004
    int64_t pos;
1005
    int inited_stream_count;
1006

  
1007
    nut->avf= s;
967 1008
    
1009
    av_set_pts_info(s, 60, 1, AV_TIME_BASE);
1010

  
1011
    /* main header */
1012
    pos=0;
1013
    for(;;){
1014
        if (find_startcode(bc, MAIN_STARTCODE, pos)<0){
1015
            av_log(s, AV_LOG_ERROR, "no main startcode found\n");
1016
            return -1;
1017
        }
1018
        pos= url_ftell(bc);
1019
        if(decode_main_header(nut) >= 0)
1020
            break;
1021
    }
1022
    
1023
    
1024
    s->bit_rate = 0;
1025

  
1026
    nut->stream = av_malloc(sizeof(StreamContext)*nut->stream_count);
1027

  
1028
    /* stream headers */
1029
    pos=0;
1030
    for(inited_stream_count=0; inited_stream_count < nut->stream_count;){
1031
        if (find_startcode(bc, STREAM_STARTCODE, pos)<0){
1032
            av_log(s, AV_LOG_ERROR, "not all stream headers found\n");
1033
            return -1;
1034
        }
1035
        pos= url_ftell(bc);
1036
        if(decode_stream_header(nut) >= 0)
1037
            inited_stream_count++;
1038
    }
1039

  
1040
    /* info headers */
1041
    pos=0;
1042
    for(;;){
1043
        uint64_t startcode= find_any_startcode(bc, pos);
1044
        pos= url_ftell(bc);
1045

  
1046
        if(startcode==0){
1047
            av_log(s, AV_LOG_ERROR, "EOF before video frames\n");
1048
            return -1;
1049
        }else if(startcode == KEYFRAME_STARTCODE){
1050
            url_fseek(bc, -8, SEEK_CUR); //FIXME
1051
            break;
1052
        }else if(startcode != INFO_STARTCODE){
1053
            continue;
1054
        }
1055

  
1056
        decode_info_header(nut);
1057
    }
1058

  
968 1059
    return 0;
969 1060
}
970 1061

  

Also available in: Unified diff