comparison asf.c @ 349:2bed194f8362 libavformat

seeking fixes memleaks infinite loops uninitalized variables with some luck u can seek now a few times before it dies
author michael
date Wed, 14 Jan 2004 18:18:47 +0000
parents ca519d041ea1
children 9a6c7a56405c
comparison
equal deleted inserted replaced
348:ca519d041ea1 349:2bed194f8362
39 int ds_span; /* descrambling */ 39 int ds_span; /* descrambling */
40 int ds_packet_size; 40 int ds_packet_size;
41 int ds_chunk_size; 41 int ds_chunk_size;
42 int ds_data_size; 42 int ds_data_size;
43 int ds_silence_data; 43 int ds_silence_data;
44
45 int packet_pos;
44 46
45 } ASFStream; 47 } ASFStream;
46 48
47 typedef struct { 49 typedef struct {
48 uint32_t v1; 50 uint32_t v1;
114 int packet_frag_timestamp; 116 int packet_frag_timestamp;
115 int packet_multi_size; 117 int packet_multi_size;
116 int packet_obj_size; 118 int packet_obj_size;
117 int packet_time_delta; 119 int packet_time_delta;
118 int packet_time_start; 120 int packet_time_start;
121 int packet_pos;
119 122
120 int stream_index; 123 int stream_index;
121 ASFStream* asf_st; /* currently decoded stream */ 124 ASFStream* asf_st; /* currently decoded stream */
122 } ASFContext; 125 } ASFContext;
123 126
1115 //asf->packet_size_left <= asf->packet_padsize) { 1118 //asf->packet_size_left <= asf->packet_padsize) {
1116 int ret = asf->packet_size_left + asf->packet_padsize; 1119 int ret = asf->packet_size_left + asf->packet_padsize;
1117 //printf("PacketLeftSize:%d Pad:%d Pos:%Ld\n", asf->packet_size_left, asf->packet_padsize, url_ftell(pb)); 1120 //printf("PacketLeftSize:%d Pad:%d Pos:%Ld\n", asf->packet_size_left, asf->packet_padsize, url_ftell(pb));
1118 /* fail safe */ 1121 /* fail safe */
1119 url_fskip(pb, ret); 1122 url_fskip(pb, ret);
1123 asf->packet_pos= url_ftell(&s->pb);
1120 ret = asf_get_packet(s); 1124 ret = asf_get_packet(s);
1121 //printf("READ ASF PACKET %d r:%d c:%d\n", ret, asf->packet_size_left, pc++); 1125 //printf("READ ASF PACKET %d r:%d c:%d\n", ret, asf->packet_size_left, pc++);
1122 if (ret < 0 || url_feof(pb)) 1126 if (ret < 0 || url_feof(pb))
1123 return -EIO; 1127 return -EIO;
1124 asf->packet_time_start = 0; 1128 asf->packet_time_start = 0;
1133 asf->stream_index = asf->asfid2avid[num & 0x7f]; 1137 asf->stream_index = asf->asfid2avid[num & 0x7f];
1134 // sequence should be ignored! 1138 // sequence should be ignored!
1135 DO_2BITS(asf->packet_property >> 4, asf->packet_seq, 0); 1139 DO_2BITS(asf->packet_property >> 4, asf->packet_seq, 0);
1136 DO_2BITS(asf->packet_property >> 2, asf->packet_frag_offset, 0); 1140 DO_2BITS(asf->packet_property >> 2, asf->packet_frag_offset, 0);
1137 DO_2BITS(asf->packet_property, asf->packet_replic_size, 0); 1141 DO_2BITS(asf->packet_property, asf->packet_replic_size, 0);
1138 1142 //printf("key:%d stream:%d seq:%d offset:%d replic_size:%d\n", asf->packet_key_frame, asf->stream_index, asf->packet_seq, //asf->packet_frag_offset, asf->packet_replic_size);
1139 if (asf->packet_replic_size > 1) { 1143 if (asf->packet_replic_size > 1) {
1140 // it should be always at least 8 bytes - FIXME validate 1144 // it should be always at least 8 bytes - FIXME validate
1141 asf->packet_obj_size = get_le32(pb); 1145 asf->packet_obj_size = get_le32(pb);
1142 asf->packet_frag_timestamp = get_le32(pb); // timestamp 1146 asf->packet_frag_timestamp = get_le32(pb); // timestamp
1143 if (asf->packet_replic_size > 8) 1147 if (asf->packet_replic_size > 8)
1226 /* new packet */ 1230 /* new packet */
1227 av_new_packet(&asf_st->pkt, asf->packet_obj_size); 1231 av_new_packet(&asf_st->pkt, asf->packet_obj_size);
1228 asf_st->seq = asf->packet_seq; 1232 asf_st->seq = asf->packet_seq;
1229 asf_st->pkt.pts = asf->packet_frag_timestamp - asf->hdr.preroll; 1233 asf_st->pkt.pts = asf->packet_frag_timestamp - asf->hdr.preroll;
1230 asf_st->pkt.stream_index = asf->stream_index; 1234 asf_st->pkt.stream_index = asf->stream_index;
1235 asf_st->packet_pos= asf->packet_pos;
1236 //printf("new packet: stream:%d key:%d packet_key:%d audio:%d\n",
1237 //asf->stream_index, asf->packet_key_frame, asf_st->pkt.flags & PKT_FLAG_KEY,
1238 //s->streams[asf->stream_index]->codec.codec_type == CODEC_TYPE_AUDIO);
1231 if (s->streams[asf->stream_index]->codec.codec_type == CODEC_TYPE_AUDIO) 1239 if (s->streams[asf->stream_index]->codec.codec_type == CODEC_TYPE_AUDIO)
1232 asf->packet_key_frame = 1; 1240 asf->packet_key_frame = 1;
1233 if (asf->packet_key_frame) 1241 if (asf->packet_key_frame)
1234 asf_st->pkt.flags |= PKT_FLAG_KEY; 1242 asf_st->pkt.flags |= PKT_FLAG_KEY;
1235 } 1243 }
1302 // If information is not reset, read_packet fails due to 1310 // If information is not reset, read_packet fails due to
1303 // leftover information from previous reads 1311 // leftover information from previous reads
1304 static void asf_reset_header(AVFormatContext *s) 1312 static void asf_reset_header(AVFormatContext *s)
1305 { 1313 {
1306 ASFContext *asf = s->priv_data; 1314 ASFContext *asf = s->priv_data;
1315 ASFStream *asf_st;
1316 int i;
1307 1317
1308 asf->packet_nb_frames = 0; 1318 asf->packet_nb_frames = 0;
1309 asf->packet_timestamp_start = -1; 1319 asf->packet_timestamp_start = -1;
1310 asf->packet_timestamp_end = -1; 1320 asf->packet_timestamp_end = -1;
1311 asf->packet_size_left = 0; 1321 asf->packet_size_left = 0;
1324 asf->packet_frag_timestamp = 0; 1334 asf->packet_frag_timestamp = 0;
1325 asf->packet_multi_size = 0; 1335 asf->packet_multi_size = 0;
1326 asf->packet_obj_size = 0; 1336 asf->packet_obj_size = 0;
1327 asf->packet_time_delta = 0; 1337 asf->packet_time_delta = 0;
1328 asf->packet_time_start = 0; 1338 asf->packet_time_start = 0;
1339
1340 for(i=0; i<s->nb_streams; i++){
1341 asf_st= s->streams[i]->priv_data;
1342 av_free_packet(&asf_st->pkt);
1343 asf_st->frag_offset=0;
1344 asf_st->seq=0;
1345 }
1346 asf->asf_st= NULL;
1329 } 1347 }
1330 1348
1331 static int64_t asf_read_pts(AVFormatContext *s, int64_t *ppos, int stream_index) 1349 static int64_t asf_read_pts(AVFormatContext *s, int64_t *ppos, int stream_index)
1332 { 1350 {
1333 ASFContext *asf = s->priv_data; 1351 ASFContext *asf = s->priv_data;
1334 AVPacket pkt1, *pkt = &pkt1; 1352 AVPacket pkt1, *pkt = &pkt1;
1353 ASFStream *asf_st;
1354 int64_t pts;
1335 int64_t pos= *ppos; 1355 int64_t pos= *ppos;
1336 int64_t pts;
1337 1356
1338 // ensure we are on the packet boundry 1357 // ensure we are on the packet boundry
1339 assert(pos % asf->packet_size == 0); 1358 assert(pos % asf->packet_size == 0);
1340 1359 //printf("asf_read_pts\n");
1341 url_fseek(&s->pb, pos + s->data_offset, SEEK_SET); 1360 url_fseek(&s->pb, pos + s->data_offset, SEEK_SET);
1361 asf_reset_header(s);
1342 do{ 1362 do{
1343 pos= url_ftell(&s->pb) - s->data_offset; 1363 if (av_read_frame(s, pkt) < 0){
1344 asf_reset_header(s); 1364 printf("seek failed\n");
1345 if (av_read_frame(s, pkt) < 0)
1346 return AV_NOPTS_VALUE; 1365 return AV_NOPTS_VALUE;
1366 }
1347 pts= pkt->pts; 1367 pts= pkt->pts;
1348 1368
1349 av_free_packet(pkt); 1369 av_free_packet(pkt);
1350 }while(pkt->stream_index != stream_index); 1370 }while(pkt->stream_index != stream_index || !(pkt->flags&PKT_FLAG_KEY));
1351 1371 asf_st= s->streams[stream_index]->priv_data;
1352 *ppos= pos; 1372 *ppos= asf_st->packet_pos - s->data_offset;
1373 //printf("found keyframe at %Ld stream %d stamp:%Ld\n", *ppos, stream_index, pts);
1353 1374
1354 return pts; 1375 return pts;
1355 } 1376 }
1356 1377
1357 static int asf_read_seek(AVFormatContext *s, int stream_index, int64_t pts) 1378 static int asf_read_seek(AVFormatContext *s, int stream_index, int64_t pts)
1359 ASFContext *asf = s->priv_data; 1380 ASFContext *asf = s->priv_data;
1360 AVStream *st; 1381 AVStream *st;
1361 AVPacket pkt1, *pkt; 1382 AVPacket pkt1, *pkt;
1362 int block_align; 1383 int block_align;
1363 int64_t pos; 1384 int64_t pos;
1364 int64_t pos_min, pos_max, pts_min, pts_max, cur_pts; 1385 int64_t pos_min, pos_max, pts_min, pts_max, cur_pts, pos_limit;
1365 1386
1366 pkt = &pkt1; 1387 pkt = &pkt1;
1367 1388
1368 // Validate pts 1389 // Validate pts
1369 if (pts < 0) 1390 if (pts < 0)
1384 pts_min = asf_read_pts(s, &pos_min, stream_index); 1405 pts_min = asf_read_pts(s, &pos_min, stream_index);
1385 if (pts_min == AV_NOPTS_VALUE) return -1; 1406 if (pts_min == AV_NOPTS_VALUE) return -1;
1386 1407
1387 pos_max = asf_align(s, url_filesize(url_fileno(&s->pb)) - 1 - s->data_offset); //FIXME wrong 1408 pos_max = asf_align(s, url_filesize(url_fileno(&s->pb)) - 1 - s->data_offset); //FIXME wrong
1388 pts_max = pts_min + s->duration; 1409 pts_max = pts_min + s->duration;
1389 1410 pos_limit= pos_max;
1390 while (pos_min <= pos_max) { 1411
1391 1412 while (pos_min < pos_limit) {
1392 if (pts <= pts_min) { 1413 int64_t start_pos;
1393 pos = pos_min; 1414
1394 goto found; 1415 assert(pos_limit <= pos_max);
1395 } else if (pts >= pts_max) { 1416
1396 pos = pos_max; 1417 // interpolate position (better than dichotomy)
1397 goto found; 1418 pos = (int64_t)((double)(pos_limit - pos_min) *
1398 } else { 1419 (double)(pts - pts_min) /
1399 // interpolate position (better than dichotomy) 1420 (double)(pts_max - pts_min)) + pos_min;
1400 pos = (int64_t)((double)(pos_max - pos_min) * 1421 pos= asf_align(s, pos);
1401 (double)(pts - pts_min) / 1422 if(pos <= pos_min)
1402 (double)(pts_max - pts_min)) + pos_min; 1423 pos= pos_min + asf->packet_size;
1403 pos= asf_align(s, pos); 1424 else if(pos > pos_limit)
1404 } 1425 pos= pos_limit;
1426 start_pos= pos;
1405 1427
1406 // read the next timestamp 1428 // read the next timestamp
1407 cur_pts = asf_read_pts(s, &pos, stream_index); 1429 cur_pts = asf_read_pts(s, &pos, stream_index);
1408 1430
1409 /* check if we are lucky */ 1431 if (cur_pts == AV_NOPTS_VALUE) {
1410 if (pts == cur_pts) { 1432 return -1;
1411 goto found;
1412 } else if (cur_pts == AV_NOPTS_VALUE) {
1413 return -1;
1414 } else if (pts < cur_pts) { 1433 } else if (pts < cur_pts) {
1434 pos_limit = start_pos - asf->packet_size;
1415 pos_max = pos; 1435 pos_max = pos;
1416 pts_max = asf_read_pts(s, &pos_max, stream_index); //FIXME wrong, must do backward search, or change this somehow 1436 pts_max = cur_pts;
1417 if (pts >= pts_max) {
1418 pos = pos_max;
1419 goto found;
1420 }
1421 } else { 1437 } else {
1422 pos_min = pos + asf->packet_size; 1438 pos_min = pos;
1423 pts_min = asf_read_pts(s, &pos_min, stream_index); 1439 pts_min = cur_pts;
1424 if (pts <= pts_min) { 1440 /* check if we are lucky */
1425 goto found; 1441 if (pts == cur_pts)
1426 } 1442 break;
1427 } 1443 }
1428 } 1444 }
1429 pos = pos_min; 1445 pos = pos_min;
1430 found:
1431 url_fseek(&s->pb, pos + s->data_offset, SEEK_SET); 1446 url_fseek(&s->pb, pos + s->data_offset, SEEK_SET);
1432 asf_reset_header(s); 1447 asf_reset_header(s);
1433 return 0; 1448 return 0;
1434 } 1449 }
1435 1450