Mercurial > libavformat.hg
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 |