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() ?) */