Mercurial > libavformat.hg
comparison mpegts.c @ 4615:12a7cd9178dd libavformat
Change TS seeking so it returns position/timestamp of a key frame.
Patch by Ivan Schreter, schreter gmx net
author | cehoyos |
---|---|
date | Sat, 28 Feb 2009 18:35:53 +0000 |
parents | 4d45ef755d67 |
children | 5c5fe792bb66 |
comparison
equal
deleted
inserted
replaced
4614:b4c4ee906a60 | 4615:12a7cd9178dd |
---|---|
46 MPEGTS_SECTION, | 46 MPEGTS_SECTION, |
47 }; | 47 }; |
48 | 48 |
49 typedef struct MpegTSFilter MpegTSFilter; | 49 typedef struct MpegTSFilter MpegTSFilter; |
50 | 50 |
51 typedef void PESCallback(MpegTSFilter *f, const uint8_t *buf, int len, int is_start); | 51 typedef void PESCallback(MpegTSFilter *f, const uint8_t *buf, int len, int is_start, int64_t pos); |
52 | 52 |
53 typedef struct MpegTSPESFilter { | 53 typedef struct MpegTSPESFilter { |
54 PESCallback *pes_cb; | 54 PESCallback *pes_cb; |
55 void *opaque; | 55 void *opaque; |
56 } MpegTSPESFilter; | 56 } MpegTSPESFilter; |
145 /* used to get the format */ | 145 /* used to get the format */ |
146 int data_index; | 146 int data_index; |
147 int total_size; | 147 int total_size; |
148 int pes_header_size; | 148 int pes_header_size; |
149 int64_t pts, dts; | 149 int64_t pts, dts; |
150 int64_t ts_packet_pos; /**< position of first TS packet of this PES packet */ | |
150 uint8_t header[MAX_PES_HEADER_SIZE]; | 151 uint8_t header[MAX_PES_HEADER_SIZE]; |
151 }; | 152 }; |
152 | 153 |
153 extern AVInputFormat mpegts_demuxer; | 154 extern AVInputFormat mpegts_demuxer; |
154 | 155 |
817 return pts; | 818 return pts; |
818 } | 819 } |
819 | 820 |
820 /* return non zero if a packet could be constructed */ | 821 /* return non zero if a packet could be constructed */ |
821 static void mpegts_push_data(MpegTSFilter *filter, | 822 static void mpegts_push_data(MpegTSFilter *filter, |
822 const uint8_t *buf, int buf_size, int is_start) | 823 const uint8_t *buf, int buf_size, int is_start, |
824 int64_t pos) | |
823 { | 825 { |
824 PESContext *pes = filter->u.pes_filter.opaque; | 826 PESContext *pes = filter->u.pes_filter.opaque; |
825 MpegTSContext *ts = pes->ts; | 827 MpegTSContext *ts = pes->ts; |
826 const uint8_t *p; | 828 const uint8_t *p; |
827 int len, code; | 829 int len, code; |
830 return; | 832 return; |
831 | 833 |
832 if (is_start) { | 834 if (is_start) { |
833 pes->state = MPEGTS_HEADER; | 835 pes->state = MPEGTS_HEADER; |
834 pes->data_index = 0; | 836 pes->data_index = 0; |
837 pes->ts_packet_pos = pos; | |
835 } | 838 } |
836 p = buf; | 839 p = buf; |
837 while (buf_size > 0) { | 840 while (buf_size > 0) { |
838 switch(pes->state) { | 841 switch(pes->state) { |
839 case MPEGTS_HEADER: | 842 case MPEGTS_HEADER: |
922 if (pes->st && av_new_packet(pkt, len) == 0) { | 925 if (pes->st && av_new_packet(pkt, len) == 0) { |
923 memcpy(pkt->data, p, len); | 926 memcpy(pkt->data, p, len); |
924 pkt->stream_index = pes->st->index; | 927 pkt->stream_index = pes->st->index; |
925 pkt->pts = pes->pts; | 928 pkt->pts = pes->pts; |
926 pkt->dts = pes->dts; | 929 pkt->dts = pes->dts; |
930 /* store position of first TS packet of this PES packet */ | |
931 pkt->pos = pes->ts_packet_pos; | |
927 /* reset pts values */ | 932 /* reset pts values */ |
928 pes->pts = AV_NOPTS_VALUE; | 933 pes->pts = AV_NOPTS_VALUE; |
929 pes->dts = AV_NOPTS_VALUE; | 934 pes->dts = AV_NOPTS_VALUE; |
930 ts->stop_parse = 1; | 935 ts->stop_parse = 1; |
931 return; | 936 return; |
1043 { | 1048 { |
1044 AVFormatContext *s = ts->stream; | 1049 AVFormatContext *s = ts->stream; |
1045 MpegTSFilter *tss; | 1050 MpegTSFilter *tss; |
1046 int len, pid, cc, cc_ok, afc, is_start; | 1051 int len, pid, cc, cc_ok, afc, is_start; |
1047 const uint8_t *p, *p_end; | 1052 const uint8_t *p, *p_end; |
1053 int64_t pos; | |
1048 | 1054 |
1049 pid = AV_RB16(packet + 1) & 0x1fff; | 1055 pid = AV_RB16(packet + 1) & 0x1fff; |
1050 if(pid && discard_pid(ts, pid)) | 1056 if(pid && discard_pid(ts, pid)) |
1051 return; | 1057 return; |
1052 is_start = packet[1] & 0x40; | 1058 is_start = packet[1] & 0x40; |
1077 /* if past the end of packet, ignore */ | 1083 /* if past the end of packet, ignore */ |
1078 p_end = packet + TS_PACKET_SIZE; | 1084 p_end = packet + TS_PACKET_SIZE; |
1079 if (p >= p_end) | 1085 if (p >= p_end) |
1080 return; | 1086 return; |
1081 | 1087 |
1082 ts->pos47= url_ftell(ts->stream->pb) % ts->raw_packet_size; | 1088 pos = url_ftell(ts->stream->pb); |
1089 ts->pos47= pos % ts->raw_packet_size; | |
1083 | 1090 |
1084 if (tss->type == MPEGTS_SECTION) { | 1091 if (tss->type == MPEGTS_SECTION) { |
1085 if (is_start) { | 1092 if (is_start) { |
1086 /* pointer field present */ | 1093 /* pointer field present */ |
1087 len = *p++; | 1094 len = *p++; |
1105 write_section_data(s, tss, | 1112 write_section_data(s, tss, |
1106 p, p_end - p, 0); | 1113 p, p_end - p, 0); |
1107 } | 1114 } |
1108 } | 1115 } |
1109 } else { | 1116 } else { |
1117 // Note: The position here points actually behind the current packet. | |
1110 tss->u.pes_filter.pes_cb(tss, | 1118 tss->u.pes_filter.pes_cb(tss, |
1111 p, p_end - p, is_start); | 1119 p, p_end - p, is_start, pos - ts->raw_packet_size); |
1112 } | 1120 } |
1113 } | 1121 } |
1114 | 1122 |
1115 /* XXX: try to find a better synchro over several packets (use | 1123 /* XXX: try to find a better synchro over several packets (use |
1116 get_packet_size() ?) */ | 1124 get_packet_size() ?) */ |