Mercurial > libavformat.hg
comparison mpeg.c @ 346:e154eb1b7149 libavformat
caching of timestamps for mpeg-ps so seeking is faster
move (av_)find_stream_index() to utils.c as its usefull outside mpeg.c
assert checking enabled, to find bugs quicker, should obviously be disabled later
(av_)add_index_entry() inserts new entries so that the list stays ordered and updates entries if already in it
(av_)index_search_timestamp() cleanup (kill ugly goto) and shorter
author | michael |
---|---|
date | Tue, 13 Jan 2004 22:02:49 +0000 |
parents | f6b2b0718235 |
children | 6770ca07abe2 |
comparison
equal
deleted
inserted
replaced
345:d94c6fd7b95e | 346:e154eb1b7149 |
---|---|
18 */ | 18 */ |
19 #include "avformat.h" | 19 #include "avformat.h" |
20 | 20 |
21 #define MAX_PAYLOAD_SIZE 4096 | 21 #define MAX_PAYLOAD_SIZE 4096 |
22 //#define DEBUG_SEEK | 22 //#define DEBUG_SEEK |
23 | |
24 #undef NDEBUG | |
25 #include <assert.h> | |
23 | 26 |
24 typedef struct { | 27 typedef struct { |
25 uint8_t buffer[MAX_PAYLOAD_SIZE]; | 28 uint8_t buffer[MAX_PAYLOAD_SIZE]; |
26 int buffer_ptr; | 29 int buffer_ptr; |
27 int nb_frames; /* number of starting frame encountered (AC3) */ | 30 int nb_frames; /* number of starting frame encountered (AC3) */ |
900 get_byte(&s->pb); | 903 get_byte(&s->pb); |
901 get_byte(&s->pb); | 904 get_byte(&s->pb); |
902 len -= 3; | 905 len -= 3; |
903 } | 906 } |
904 } | 907 } |
908 if(dts != AV_NOPTS_VALUE && ppos){ | |
909 int i; | |
910 for(i=0; i<s->nb_streams; i++){ | |
911 if(startcode == s->streams[i]->id) { | |
912 av_add_index_entry(s->streams[i], *ppos, dts, 0 /* FIXME keyframe? */); | |
913 } | |
914 } | |
915 } | |
916 | |
905 *pstart_code = startcode; | 917 *pstart_code = startcode; |
906 *ppts = pts; | 918 *ppts = pts; |
907 *pdts = dts; | 919 *pdts = dts; |
908 return len; | 920 return len; |
909 } | 921 } |
911 static int mpegps_read_packet(AVFormatContext *s, | 923 static int mpegps_read_packet(AVFormatContext *s, |
912 AVPacket *pkt) | 924 AVPacket *pkt) |
913 { | 925 { |
914 AVStream *st; | 926 AVStream *st; |
915 int len, startcode, i, type, codec_id; | 927 int len, startcode, i, type, codec_id; |
916 int64_t pts, dts; | 928 int64_t pts, dts, dummy_pos; //dummy_pos is needed for the index building to work |
917 | 929 |
918 redo: | 930 redo: |
919 len = mpegps_read_pes_header(s, NULL, &startcode, &pts, &dts, 1); | 931 len = mpegps_read_pes_header(s, &dummy_pos, &startcode, &pts, &dts, 1); |
920 if (len < 0) | 932 if (len < 0) |
921 return len; | 933 return len; |
922 | 934 |
923 /* now find stream */ | 935 /* now find stream */ |
924 for(i=0;i<s->nb_streams;i++) { | 936 for(i=0;i<s->nb_streams;i++) { |
1020 #endif | 1032 #endif |
1021 *ppos = pos; | 1033 *ppos = pos; |
1022 return dts; | 1034 return dts; |
1023 } | 1035 } |
1024 | 1036 |
1025 static int find_stream_index(AVFormatContext *s) | |
1026 { | |
1027 int i; | |
1028 AVStream *st; | |
1029 | |
1030 if (s->nb_streams <= 0) | |
1031 return -1; | |
1032 for(i = 0; i < s->nb_streams; i++) { | |
1033 st = s->streams[i]; | |
1034 if (st->codec.codec_type == CODEC_TYPE_VIDEO) { | |
1035 return i; | |
1036 } | |
1037 } | |
1038 return 0; | |
1039 } | |
1040 | |
1041 static int mpegps_read_seek(AVFormatContext *s, | 1037 static int mpegps_read_seek(AVFormatContext *s, |
1042 int stream_index, int64_t timestamp) | 1038 int stream_index, int64_t timestamp) |
1043 { | 1039 { |
1044 int64_t pos_min, pos_max, pos; | 1040 int64_t pos_min, pos_max, pos; |
1045 int64_t dts_min, dts_max, dts; | 1041 int64_t dts_min, dts_max, dts; |
1042 int index; | |
1043 AVStream *st; | |
1046 | 1044 |
1047 timestamp = (timestamp * 90000) / AV_TIME_BASE; | 1045 timestamp = (timestamp * 90000) / AV_TIME_BASE; |
1048 | 1046 |
1049 #ifdef DEBUG_SEEK | 1047 #ifdef DEBUG_SEEK |
1050 printf("read_seek: %d %0.3f\n", stream_index, timestamp / 90000.0); | 1048 printf("read_seek: %d %0.3f\n", stream_index, timestamp / 90000.0); |
1051 #endif | 1049 #endif |
1052 | 1050 |
1053 /* XXX: find stream_index by looking at the first PES packet found */ | 1051 /* XXX: find stream_index by looking at the first PES packet found */ |
1054 if (stream_index < 0) { | 1052 if (stream_index < 0) { |
1055 stream_index = find_stream_index(s); | 1053 stream_index = av_find_default_stream_index(s); |
1056 if (stream_index < 0) | 1054 if (stream_index < 0) |
1057 return -1; | 1055 return -1; |
1058 } | 1056 } |
1059 pos_min = 0; | 1057 |
1060 dts_min = mpegps_read_dts(s, stream_index, &pos_min, 1); | 1058 dts_max= |
1061 if (dts_min == AV_NOPTS_VALUE) { | 1059 dts_min= AV_NOPTS_VALUE; |
1062 /* we can reach this case only if no PTS are present in | 1060 |
1063 the whole stream */ | 1061 st= s->streams[stream_index]; |
1064 return -1; | 1062 if(st->index_entries){ |
1065 } | 1063 AVIndexEntry *e; |
1066 pos_max = url_filesize(url_fileno(&s->pb)) - 1; | 1064 |
1067 dts_max = mpegps_read_dts(s, stream_index, &pos_max, 0); | 1065 index= av_index_search_timestamp(st, timestamp); |
1066 e= &st->index_entries[index]; | |
1067 if(e->timestamp <= timestamp){ | |
1068 pos_min= e->pos; | |
1069 dts_min= e->timestamp; | |
1070 #ifdef DEBUG_SEEK | |
1071 printf("unsing cached pos_min=0x%llx dts_min=%0.3f\n", | |
1072 pos_min,dts_min / 90000.0); | |
1073 #endif | |
1074 }else{ | |
1075 assert(index==0); | |
1076 } | |
1077 index++; | |
1078 if(index < st->nb_index_entries){ | |
1079 e= &st->index_entries[index]; | |
1080 assert(e->timestamp >= timestamp); | |
1081 pos_max= e->pos; | |
1082 dts_max= e->timestamp; | |
1083 #ifdef DEBUG_SEEK | |
1084 printf("unsing cached pos_max=0x%llx dts_max=%0.3f\n", | |
1085 pos_max,dts_max / 90000.0); | |
1086 #endif | |
1087 } | |
1088 } | |
1089 | |
1090 if(dts_min == AV_NOPTS_VALUE){ | |
1091 pos_min = 0; | |
1092 dts_min = mpegps_read_dts(s, stream_index, &pos_min, 1); | |
1093 if (dts_min == AV_NOPTS_VALUE) { | |
1094 /* we can reach this case only if no PTS are present in | |
1095 the whole stream */ | |
1096 return -1; | |
1097 } | |
1098 } | |
1099 if(dts_max == AV_NOPTS_VALUE){ | |
1100 pos_max = url_filesize(url_fileno(&s->pb)) - 1; | |
1101 dts_max = mpegps_read_dts(s, stream_index, &pos_max, 0); | |
1102 } | |
1068 | 1103 |
1069 while (pos_min <= pos_max) { | 1104 while (pos_min <= pos_max) { |
1070 #ifdef DEBUG_SEEK | 1105 #ifdef DEBUG_SEEK |
1071 printf("pos_min=0x%llx pos_max=0x%llx dts_min=%0.3f dts_max=%0.3f\n", | 1106 printf("pos_min=0x%llx pos_max=0x%llx dts_min=%0.3f dts_max=%0.3f\n", |
1072 pos_min, pos_max, | 1107 pos_min, pos_max, |