Changeset a9ef21bb in ffmpeg
- Timestamp:
- Dec 18, 2011, 10:11:05 PM (13 years ago)
- Branches:
- master
- Children:
- f371396d
- Parents:
- 1c73391d (diff), 0e764cf5 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - git-author:
- Michael Niedermayer <michaelni@gmx.at> (12/18/11 22:10:58)
- git-committer:
- Michael Niedermayer <michaelni@gmx.at> (12/18/11 22:11:05)
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
libavformat/mxfdec.c
r1c73391d ra9ef21bb 149 149 int index_sid; 150 150 int body_sid; 151 int slice_count;152 151 AVRational index_edit_rate; 153 152 uint64_t index_start_position; 154 153 uint64_t index_duration; 155 int *slice;156 int *element_delta;157 int nb_delta_entries;158 154 int8_t *temporal_offset_entries; 159 155 int *flag_entries; 160 156 uint64_t *stream_offset_entries; 161 uint32_t **slice_offset_entries;162 157 int nb_index_entries; 163 158 } MXFIndexTableSegment; … … 177 172 enum MXFMetadataSetType type; 178 173 } MXFMetadataSet; 174 175 /* decoded index table */ 176 typedef struct { 177 int index_sid; 178 int body_sid; 179 int nb_ptses; /* number of PTSes or total duration of index */ 180 int64_t first_dts; /* DTS = EditUnit + first_dts */ 181 int64_t *ptses; /* maps EditUnit -> PTS */ 182 int nb_segments; 183 MXFIndexTableSegment **segments; /* sorted by IndexStartPosition */ 184 AVIndexEntry *fake_index; /* used for calling ff_index_search_timestamp() */ 185 } MXFIndexTable; 179 186 180 187 typedef struct { … … 199 206 int last_forward_partition; 200 207 int current_edit_unit; 201 int current_stream; 202 int d10; 203 int broken_index; 204 int64_t first_dts; /* DTS = EditUnit + first_dts */ 205 int64_t *ptses; /* maps EditUnit -> PTS */ 206 int nb_ptses; 208 int nb_index_tables; 209 MXFIndexTable *index_tables; 207 210 } MXFContext; 208 211 … … 381 384 } 382 385 383 static int mxf_read_packet_old(AVFormatContext *s, AVPacket *pkt)384 {385 KLVPacket klv;386 387 while (!url_feof(s->pb)) {388 if (klv_read_packet(&klv, s->pb) < 0)389 return -1;390 PRINT_KEY(s, "read packet", klv.key);391 av_dlog(s, "size %"PRIu64" offset %#"PRIx64"\n", klv.length, klv.offset);392 if (IS_KLV_KEY(klv.key, mxf_encrypted_triplet_key)) {393 int res = mxf_decrypt_triplet(s, pkt, &klv);394 if (res < 0) {395 av_log(s, AV_LOG_ERROR, "invalid encoded triplet\n");396 return -1;397 }398 return 0;399 }400 if (IS_KLV_KEY(klv.key, mxf_essence_element_key) ||401 IS_KLV_KEY(klv.key, mxf_avid_essence_element_key)) {402 int index = mxf_get_stream_index(s, &klv);403 if (index < 0) {404 av_log(s, AV_LOG_ERROR, "error getting stream index %d\n", AV_RB32(klv.key+12));405 goto skip;406 }407 if (s->streams[index]->discard == AVDISCARD_ALL)408 goto skip;409 /* check for 8 channels AES3 element */410 if (klv.key[12] == 0x06 && klv.key[13] == 0x01 && klv.key[14] == 0x10) {411 if (mxf_get_d10_aes3_packet(s->pb, s->streams[index], pkt, klv.length) < 0) {412 av_log(s, AV_LOG_ERROR, "error reading D-10 aes3 frame\n");413 return -1;414 }415 } else {416 int ret = av_get_packet(s->pb, pkt, klv.length);417 if (ret < 0)418 return ret;419 }420 pkt->stream_index = index;421 pkt->pos = klv.offset;422 return 0;423 } else424 skip:425 avio_skip(s->pb, klv.length);426 }427 return AVERROR_EOF;428 }429 430 static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt)431 {432 MXFContext *mxf = s->priv_data;433 AVIndexEntry *e;434 int ret;435 int64_t ret64;436 KLVPacket klv;437 AVStream *st;438 439 /* TODO: better logic for this?440 * only files that lack all index segments prior to the essence need this */441 if (!s->pb->seekable && mxf->op != OPAtom || mxf->d10 || mxf->broken_index)442 return mxf_read_packet_old(s, pkt);443 444 if (mxf->current_stream >= s->nb_streams) {445 mxf->current_edit_unit++;446 mxf->current_stream = 0;447 }448 449 st = s->streams[mxf->current_stream];450 451 if (mxf->current_edit_unit >= st->nb_index_entries)452 return AVERROR_EOF;453 454 e = &st->index_entries[mxf->current_edit_unit];455 456 if ((ret64 = avio_seek(s->pb, e->pos, SEEK_SET)) < 0)457 return ret64;458 459 if (mxf->op == OPAtom) {460 /* OPAtom - no KL, just essence */461 if ((ret = av_get_packet(s->pb, pkt, e->size)) != e->size)462 return ret < 0 ? ret : AVERROR_EOF;463 } else {464 /* read KL, read L bytes of essence */465 if ((ret = klv_read_packet(&klv, s->pb)) < 0)466 return ret;467 468 /* untested, but looks OK */469 if (IS_KLV_KEY(klv.key, mxf_encrypted_triplet_key)) {470 int res = mxf_decrypt_triplet(s, pkt, &klv);471 if (res < 0) {472 av_log(s, AV_LOG_ERROR, "invalid encoded triplet\n");473 return -1;474 }475 return 0;476 }477 478 if ((ret = av_get_packet(s->pb, pkt, klv.length)) != klv.length)479 return ret < 0 ? ret : AVERROR_EOF;480 481 pkt->pos = e->pos;482 }483 484 if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && mxf->ptses && mxf->current_edit_unit < mxf->nb_ptses) {485 pkt->dts = mxf->current_edit_unit + mxf->first_dts;486 pkt->pts = mxf->ptses[mxf->current_edit_unit];487 }488 489 pkt->stream_index = mxf->current_stream++;490 491 return 0;492 }493 494 386 static int mxf_read_primer_pack(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset) 495 387 { … … 769 661 } 770 662 771 static int mxf_read_delta_entry_array(AVIOContext *pb, MXFIndexTableSegment *segment)772 {773 int i, length;774 775 segment->nb_delta_entries = avio_rb32(pb);776 length = avio_rb32(pb);777 778 if (!(segment->slice = av_calloc(segment->nb_delta_entries, sizeof(*segment->slice))) ||779 !(segment->element_delta = av_calloc(segment->nb_delta_entries, sizeof(*segment->element_delta))))780 return AVERROR(ENOMEM);781 782 for (i = 0; i < segment->nb_delta_entries; i++) {783 avio_r8(pb); /* PosTableIndex */784 segment->slice[i] = avio_r8(pb);785 segment->element_delta[i] = avio_rb32(pb);786 }787 return 0;788 }789 790 663 static int mxf_read_index_entry_array(AVIOContext *pb, MXFIndexTableSegment *segment) 791 664 { … … 798 671 !(segment->flag_entries = av_calloc(segment->nb_index_entries, sizeof(*segment->flag_entries))) || 799 672 !(segment->stream_offset_entries = av_calloc(segment->nb_index_entries, sizeof(*segment->stream_offset_entries)))) 800 return AVERROR(ENOMEM);801 802 if (segment->slice_count &&803 !(segment->slice_offset_entries = av_calloc(segment->nb_index_entries, sizeof(*segment->slice_offset_entries))))804 673 return AVERROR(ENOMEM); 805 674 … … 809 678 segment->flag_entries[i] = avio_r8(pb); 810 679 segment->stream_offset_entries[i] = avio_rb64(pb); 811 if (segment->slice_count) { 812 if (!(segment->slice_offset_entries[i] = av_calloc(segment->slice_count, sizeof(**segment->slice_offset_entries)))) 813 return AVERROR(ENOMEM); 814 815 for (j = 0; j < segment->slice_count; j++) 816 segment->slice_offset_entries[i][j] = avio_rb32(pb); 817 } 818 819 avio_skip(pb, length - 11 - 4 * segment->slice_count); 680 avio_skip(pb, length - 11); 820 681 } 821 682 return 0; … … 838 699 av_dlog(NULL, "BodySID %d\n", segment->body_sid); 839 700 break; 840 case 0x3F08:841 segment->slice_count = avio_r8(pb);842 av_dlog(NULL, "SliceCount %d\n", segment->slice_count);843 break;844 case 0x3F09:845 av_dlog(NULL, "DeltaEntryArray found\n");846 return mxf_read_delta_entry_array(pb, segment);847 701 case 0x3F0A: 848 702 av_dlog(NULL, "IndexEntryArray found\n"); … … 1002 856 }; 1003 857 1004 static UID mxf_d10_ul = { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x01,0x01 };1005 1006 858 static int mxf_get_sorted_table_segments(MXFContext *mxf, int *nb_sorted_segments, MXFIndexTableSegment ***sorted_segments) 1007 859 { … … 1090 942 1091 943 /** 1092 * Returns the lengthof the essence container with given BodySID, or zero if unknown944 * Returns the end position of the essence container with given BodySID, or zero if unknown 1093 945 */ 1094 static int64_t mxf_essence_container_ length(MXFContext *mxf, int body_sid)946 static int64_t mxf_essence_container_end(MXFContext *mxf, int body_sid) 1095 947 { 1096 948 int x; … … 1106 958 return 0; 1107 959 1108 ret +=p->essence_length;960 ret = p->essence_offset + p->essence_length; 1109 961 } 1110 962 … … 1112 964 } 1113 965 1114 static int mxf_parse_index(MXFContext *mxf, int track_id, AVStream *st, MXFIndexTableSegment **sorted_segments, int nb_sorted_segments) 1115 { 1116 int64_t accumulated_offset = 0; 1117 int j, k, l, ret; 1118 int n_delta = track_id - 1; /* TrackID = 1-based stream index */ 1119 1120 if (track_id < 1) { 1121 av_log(mxf->fc, AV_LOG_ERROR, "TrackID not positive: %i\n", track_id); 1122 return AVERROR_INVALIDDATA; 1123 } 1124 1125 for (j = 0; j < nb_sorted_segments; j++) { 1126 int duration, sample_duration = 1, last_sample_size = 0; 1127 int64_t segment_size; 1128 MXFIndexTableSegment *tableseg = sorted_segments[j]; 1129 int index_delta = 1, last_size_unknown = 0; 1130 int64_t last_pos = 0; 1131 1132 /* reset accumulated_offset on BodySID change */ 1133 if (j > 0 && tableseg->body_sid != sorted_segments[j-1]->body_sid) 1134 accumulated_offset = 0; 1135 1136 if (tableseg->nb_index_entries == 2 * tableseg->index_duration + 1) { 1137 /* Avid index - duplicate entries and total size as last entry */ 1138 index_delta = 2; 1139 } 1140 1141 if (n_delta >= tableseg->nb_delta_entries && st->index != 0) 1142 continue; 1143 duration = tableseg->index_duration > 0 ? tableseg->index_duration : 1144 st->duration - st->nb_index_entries; 1145 segment_size = tableseg->edit_unit_byte_count * duration; 1146 /* check small EditUnitByteCount for audio */ 1147 if (tableseg->edit_unit_byte_count && tableseg->edit_unit_byte_count < 32 1148 && !tableseg->index_duration) { 1149 /* duration might be prime relative to the new sample_duration, 1150 * which means we need to handle the last frame differently */ 1151 sample_duration = 8192; 1152 last_sample_size = (duration % sample_duration) * tableseg->edit_unit_byte_count; 1153 tableseg->edit_unit_byte_count *= sample_duration; 1154 duration /= sample_duration; 1155 if (last_sample_size) duration++; 1156 } 1157 1158 if (duration <= 0) { 1159 av_log(mxf->fc, AV_LOG_WARNING, "0 duration in index for stream %i\n", st->index); 1160 mxf->broken_index = 1; 1161 return 0; 1162 } 1163 1164 for (k = l = 0; k < duration; k++, l += index_delta) { 1165 int64_t pos; 1166 int size, flags = 0; 1167 1168 if (l < tableseg->nb_index_entries) { 1169 pos = tableseg->stream_offset_entries[l]; 1170 if (n_delta < tableseg->nb_delta_entries) { 1171 if (n_delta < tableseg->nb_delta_entries - 1) { 1172 size = 1173 tableseg->slice_offset_entries[l][tableseg->slice[n_delta+1]-1] + 1174 tableseg->element_delta[n_delta+1] - 1175 tableseg->element_delta[n_delta]; 1176 if (tableseg->slice[n_delta] > 0) 1177 size -= tableseg->slice_offset_entries[l][tableseg->slice[n_delta]-1]; 1178 } else if (l < tableseg->nb_index_entries - 1) { 1179 size = tableseg->stream_offset_entries[l+1] - 1180 tableseg->stream_offset_entries[l] - 1181 tableseg->slice_offset_entries[l][tableseg->slice[tableseg->nb_delta_entries-1]-1] - 1182 tableseg->element_delta[tableseg->nb_delta_entries-1]; 1183 } else 1184 size = 0; 1185 if (tableseg->slice[n_delta] > 0) 1186 pos += tableseg->slice_offset_entries[l][tableseg->slice[n_delta]-1]; 1187 pos += tableseg->element_delta[n_delta]; 1188 } else 1189 size = 0; 1190 flags = !(tableseg->flag_entries[l] & 0x30) ? AVINDEX_KEYFRAME : 0; 966 /* EditUnit -> absolute offset */ 967 static int mxf_edit_unit_absolute_offset(MXFContext *mxf, MXFIndexTable *index_table, int64_t edit_unit, int64_t *edit_unit_out, int64_t *offset_out, int nag) 968 { 969 int i; 970 int offset_temp = 0; 971 972 for (i = 0; i < index_table->nb_segments; i++) { 973 MXFIndexTableSegment *s = index_table->segments[i]; 974 975 edit_unit = FFMAX(edit_unit, s->index_start_position); /* clamp if trying to seek before start */ 976 977 if (edit_unit < s->index_start_position + s->index_duration) { 978 int64_t index = edit_unit - s->index_start_position; 979 980 if (s->edit_unit_byte_count) 981 offset_temp += s->edit_unit_byte_count * index; 982 else if (s->nb_index_entries) { 983 if (s->nb_index_entries == 2 * s->index_duration + 1) 984 index *= 2; /* Avid index */ 985 986 if (index < 0 || index > s->nb_index_entries) { 987 av_log(mxf->fc, AV_LOG_ERROR, "IndexSID %i segment at %"PRId64" IndexEntryArray too small\n", 988 index_table->index_sid, s->index_start_position); 989 return AVERROR_INVALIDDATA; 990 } 991 992 offset_temp = s->stream_offset_entries[index]; 1191 993 } else { 1192 pos = (int64_t)k * tableseg->edit_unit_byte_count + accumulated_offset; 1193 if (n_delta < tableseg->nb_delta_entries - 1) 1194 size = tableseg->element_delta[n_delta+1] - tableseg->element_delta[n_delta]; 1195 else { 1196 /* use smaller size for last sample if we should */ 1197 if (last_sample_size && k == duration - 1) 1198 size = last_sample_size; 1199 else 1200 size = tableseg->edit_unit_byte_count; 1201 if (tableseg->nb_delta_entries) 1202 size -= tableseg->element_delta[tableseg->nb_delta_entries-1]; 1203 } 1204 if (n_delta < tableseg->nb_delta_entries) 1205 pos += tableseg->element_delta[n_delta]; 1206 flags = AVINDEX_KEYFRAME; 994 av_log(mxf->fc, AV_LOG_ERROR, "IndexSID %i segment at %"PRId64" missing EditUnitByteCount and IndexEntryArray\n", 995 index_table->index_sid, s->index_start_position); 996 return AVERROR_INVALIDDATA; 1207 997 } 1208 998 1209 if (last_size_unknown) 1210 st->index_entries[st->nb_index_entries-1].size = pos - last_pos; 1211 1212 last_size_unknown = size == 0; 1213 last_pos = pos; 1214 1215 if (mxf_absolute_bodysid_offset(mxf, tableseg->body_sid, pos, &pos) < 0) { 1216 /* probably partial file - no point going further for this stream */ 1217 break; 1218 } 1219 1220 av_dlog(mxf->fc, "Stream %d IndexEntry %d TrackID %d Offset %"PRIx64" Timestamp %"PRId64"\n", 1221 st->index, st->nb_index_entries, track_id, pos, sample_duration * st->nb_index_entries); 1222 1223 if ((ret = av_add_index_entry(st, pos, sample_duration * st->nb_index_entries, size, 0, flags)) < 0) 1224 return ret; 1225 } 1226 1227 if (last_size_unknown) { 1228 int64_t ecl = mxf_essence_container_length(mxf, tableseg->body_sid); 1229 1230 if (ecl > 0) 1231 st->index_entries[st->nb_index_entries-1].size = ecl - last_pos; 1232 } 1233 1234 accumulated_offset += segment_size; 1235 } 1236 1237 return 0; 1238 } 1239 1240 static int mxf_compute_ptses(MXFContext *mxf, MXFIndexTableSegment **sorted_segments, int nb_sorted_segments) 1241 { 1242 int ret, i, j, x; 999 if (edit_unit_out) 1000 *edit_unit_out = edit_unit; 1001 1002 return mxf_absolute_bodysid_offset(mxf, index_table->body_sid, offset_temp, offset_out); 1003 } else { 1004 /* EditUnitByteCount == 0 for VBR indexes, which is fine since they use explicit StreamOffsets */ 1005 offset_temp += s->edit_unit_byte_count * s->index_duration; 1006 } 1007 } 1008 1009 if (nag) 1010 av_log(mxf->fc, AV_LOG_ERROR, "failed to map EditUnit %"PRId64" in IndexSID %i to an offset\n", edit_unit, index_table->index_sid); 1011 1012 return AVERROR_INVALIDDATA; 1013 } 1014 1015 static int mxf_compute_ptses_fake_index(MXFContext *mxf, MXFIndexTable *index_table) 1016 { 1017 int i, j, x; 1243 1018 int8_t max_temporal_offset = -128; 1244 1019 1245 1020 /* first compute how many entries we have */ 1246 for (i = 0; i < nb_sorted_segments; i++) {1247 MXFIndexTableSegment *s = sorted_segments[i];1021 for (i = 0; i < index_table->nb_segments; i++) { 1022 MXFIndexTableSegment *s = index_table->segments[i]; 1248 1023 1249 1024 if (!s->nb_index_entries) 1250 1025 return 0; /* no TemporalOffsets */ 1251 1026 1252 if (s->nb_index_entries == 2 * s->index_duration + 1) 1253 mxf->nb_ptses += s->index_duration; /* Avid index */ 1254 else 1255 mxf->nb_ptses += s->nb_index_entries; 1027 index_table->nb_ptses += s->index_duration; 1256 1028 } 1257 1029 1258 1030 /* paranoid check */ 1259 if ( mxf->nb_ptses <= 0)1031 if (index_table->nb_ptses <= 0) 1260 1032 return 0; 1261 1033 1262 if (!(mxf->ptses = av_calloc(mxf->nb_ptses, sizeof(int64_t)))) 1034 if (!(index_table->ptses = av_calloc(index_table->nb_ptses, sizeof(int64_t))) || 1035 !(index_table->fake_index = av_calloc(index_table->nb_ptses, sizeof(AVIndexEntry)))) { 1036 av_freep(&index_table->ptses); 1263 1037 return AVERROR(ENOMEM); 1038 } 1264 1039 1265 1040 /* we may have a few bad TemporalOffsets 1266 1041 * make sure the corresponding PTSes don't have the bogus value 0 */ 1267 for (x = 0; x < mxf->nb_ptses; x++)1268 mxf->ptses[x] = AV_NOPTS_VALUE;1042 for (x = 0; x < index_table->nb_ptses; x++) 1043 index_table->ptses[x] = AV_NOPTS_VALUE; 1269 1044 1270 1045 /** … … 1295 1070 * The latter makes DTS <= PTS. 1296 1071 */ 1297 for (i = x = 0; i < nb_sorted_segments; i++) {1298 MXFIndexTableSegment *s = sorted_segments[i];1072 for (i = x = 0; i < index_table->nb_segments; i++) { 1073 MXFIndexTableSegment *s = index_table->segments[i]; 1299 1074 int index_delta = 1; 1300 1075 … … 1306 1081 int index = x + offset; 1307 1082 1308 if (index < 0 || index >= mxf->nb_ptses) { 1083 index_table->fake_index[x].timestamp = x; 1084 index_table->fake_index[x].flags = !(s->flag_entries[j] & 0x30) ? AVINDEX_KEYFRAME : 0; 1085 1086 if (index < 0 || index >= index_table->nb_ptses) { 1309 1087 av_log(mxf->fc, AV_LOG_ERROR, 1310 1088 "index entry %i + TemporalOffset %i = %i, which is out of bounds\n", … … 1313 1091 } 1314 1092 1315 mxf->ptses[index] = x;1093 index_table->ptses[index] = x; 1316 1094 max_temporal_offset = FFMAX(max_temporal_offset, offset); 1317 1095 } 1318 1096 } 1319 1097 1320 mxf->first_dts = -max_temporal_offset; 1321 1322 return 0; 1098 index_table->first_dts = -max_temporal_offset; 1099 1100 return 0; 1101 } 1102 1103 /** 1104 * Sorts and collects index table segments into index tables. 1105 * Also computes PTSes if possible. 1106 */ 1107 static int mxf_compute_index_tables(MXFContext *mxf) 1108 { 1109 int i, j, k, ret, nb_sorted_segments; 1110 MXFIndexTableSegment **sorted_segments = NULL; 1111 1112 if ((ret = mxf_get_sorted_table_segments(mxf, &nb_sorted_segments, &sorted_segments)) || 1113 nb_sorted_segments <= 0) { 1114 av_log(mxf->fc, AV_LOG_WARNING, "broken or empty index\n"); 1115 return 0; 1116 } 1117 1118 /* sanity check and count unique BodySIDs/IndexSIDs */ 1119 for (i = 0; i < nb_sorted_segments; i++) { 1120 if (i == 0 || sorted_segments[i-1]->index_sid != sorted_segments[i]->index_sid) 1121 mxf->nb_index_tables++; 1122 else if (sorted_segments[i-1]->body_sid != sorted_segments[i]->body_sid) { 1123 av_log(mxf->fc, AV_LOG_ERROR, "found inconsistent BodySID\n"); 1124 ret = AVERROR_INVALIDDATA; 1125 goto finish_decoding_index; 1126 } 1127 } 1128 1129 if (!(mxf->index_tables = av_calloc(mxf->nb_index_tables, sizeof(MXFIndexTable)))) { 1130 av_log(mxf->fc, AV_LOG_ERROR, "failed to allocate index tables\n"); 1131 ret = AVERROR(ENOMEM); 1132 goto finish_decoding_index; 1133 } 1134 1135 /* distribute sorted segments to index tables */ 1136 for (i = j = 0; i < nb_sorted_segments; i++) { 1137 if (i != 0 && sorted_segments[i-1]->index_sid != sorted_segments[i]->index_sid) { 1138 /* next IndexSID */ 1139 j++; 1140 } 1141 1142 mxf->index_tables[j].nb_segments++; 1143 } 1144 1145 for (i = j = 0; j < mxf->nb_index_tables; i += mxf->index_tables[j++].nb_segments) { 1146 MXFIndexTable *t = &mxf->index_tables[j]; 1147 1148 if (!(t->segments = av_calloc(t->nb_segments, sizeof(MXFIndexTableSegment*)))) { 1149 av_log(mxf->fc, AV_LOG_ERROR, "failed to allocate IndexTableSegment pointer array\n"); 1150 ret = AVERROR(ENOMEM); 1151 goto finish_decoding_index; 1152 } 1153 1154 if (sorted_segments[i]->index_start_position) 1155 av_log(mxf->fc, AV_LOG_WARNING, "IndexSID %i starts at EditUnit %"PRId64" - seeking may not work as expected\n", 1156 sorted_segments[i]->index_sid, sorted_segments[i]->index_start_position); 1157 1158 memcpy(t->segments, &sorted_segments[i], t->nb_segments * sizeof(MXFIndexTableSegment*)); 1159 t->index_sid = sorted_segments[i]->index_sid; 1160 t->body_sid = sorted_segments[i]->body_sid; 1161 1162 if ((ret = mxf_compute_ptses_fake_index(mxf, t)) < 0) 1163 goto finish_decoding_index; 1164 1165 /* fix zero IndexDurations */ 1166 for (k = 0; k < t->nb_segments; k++) { 1167 if (t->segments[k]->index_duration) 1168 continue; 1169 1170 if (t->nb_segments > 1) 1171 av_log(mxf->fc, AV_LOG_WARNING, "IndexSID %i segment %i has zero IndexDuration and there's more than one segment\n", 1172 t->index_sid, k); 1173 1174 if (mxf->fc->nb_streams <= 0) { 1175 av_log(mxf->fc, AV_LOG_WARNING, "no streams?\n"); 1176 break; 1177 } 1178 1179 /* assume the first stream's duration is reasonable 1180 * leave index_duration = 0 on further segments in case we have any (unlikely) 1181 */ 1182 t->segments[k]->index_duration = mxf->fc->streams[0]->duration; 1183 break; 1184 } 1185 } 1186 1187 ret = 0; 1188 finish_decoding_index: 1189 av_free(sorted_segments); 1190 return ret; 1323 1191 } 1324 1192 … … 1327 1195 MXFPackage *material_package = NULL; 1328 1196 MXFPackage *temp_package = NULL; 1329 int i, j, k, ret, nb_sorted_segments; 1330 MXFIndexTableSegment **sorted_segments = NULL; 1197 int i, j, k, ret; 1331 1198 1332 1199 av_dlog(mxf->fc, "metadata sets count %d\n", mxf->metadata_sets_count); … … 1339 1206 av_log(mxf->fc, AV_LOG_ERROR, "no material package found\n"); 1340 1207 return -1; 1341 }1342 1343 if ((ret = mxf_get_sorted_table_segments(mxf, &nb_sorted_segments, &sorted_segments)) ||1344 nb_sorted_segments <= 0) {1345 av_log(mxf->fc, AV_LOG_WARNING, "broken or empty index\n");1346 mxf->broken_index = 1;1347 1208 } 1348 1209 … … 1476 1337 } 1477 1338 } 1478 1479 /* HACK: revert to the old demuxing/seeking scode for D-10 for now */1480 if (mxf_match_uid(essence_container_ul, mxf_d10_ul, 14))1481 mxf->d10 = 1;1482 1339 1483 1340 /* TODO: drop PictureEssenceCoding and SoundEssenceCompression, only check EssenceContainer */ … … 1523 1380 st->need_parsing = AVSTREAM_PARSE_TIMESTAMPS; 1524 1381 } 1525 1526 if (!mxf->broken_index && 1527 (ret = mxf_parse_index(mxf, material_track->track_id, st, sorted_segments, nb_sorted_segments))) 1528 goto fail_and_free; 1529 } 1530 1531 ret = mxf_compute_ptses(mxf, sorted_segments, nb_sorted_segments); 1532 1382 } 1383 1384 ret = 0; 1533 1385 fail_and_free: 1534 av_free(sorted_segments);1535 1386 return ret; 1536 1387 } … … 1729 1580 KLVPacket klv; 1730 1581 int64_t essence_offset = 0; 1582 int ret; 1731 1583 1732 1584 mxf->last_forward_tell = INT64_MAX; … … 1824 1676 mxf_compute_essence_containers(mxf); 1825 1677 1826 return mxf_parse_structural_metadata(mxf); 1678 /* we need to do this before computing the index tables 1679 * to be able to fill in zero IndexDurations with st->duration */ 1680 if ((ret = mxf_parse_structural_metadata(mxf)) < 0) 1681 return ret; 1682 1683 if ((ret = mxf_compute_index_tables(mxf)) < 0) 1684 return ret; 1685 1686 if (mxf->nb_index_tables > 1) { 1687 /* TODO: look up which IndexSID to use via EssenceContainerData */ 1688 av_log(mxf->fc, AV_LOG_INFO, "got %i index tables - only the first one (IndexSID %i) will be used\n", 1689 mxf->nb_index_tables, mxf->index_tables[0].index_sid); 1690 } else if (mxf->nb_index_tables == 0 && mxf->op == OPAtom) { 1691 av_log(mxf->fc, AV_LOG_ERROR, "cannot demux OPAtom without an index\n"); 1692 return AVERROR_INVALIDDATA; 1693 } 1694 1695 return 0; 1696 } 1697 1698 /** 1699 * Computes DTS and PTS for the given video packet based on its offset. 1700 */ 1701 static void mxf_packet_timestamps(MXFContext *mxf, AVPacket *pkt) 1702 { 1703 int64_t next_ofs; 1704 MXFIndexTable *t = &mxf->index_tables[0]; 1705 1706 /* find mxf->current_edit_unit so that the next edit unit starts ahead of pkt->pos */ 1707 for (;;) { 1708 if (mxf_edit_unit_absolute_offset(mxf, t, mxf->current_edit_unit + 1, NULL, &next_ofs, 0) < 0) 1709 break; 1710 1711 if (next_ofs > pkt->pos) 1712 break; 1713 1714 mxf->current_edit_unit++; 1715 } 1716 1717 if (mxf->current_edit_unit >= t->nb_ptses) 1718 return; 1719 1720 pkt->dts = mxf->current_edit_unit + t->first_dts; 1721 pkt->pts = t->ptses[mxf->current_edit_unit]; 1722 } 1723 1724 static int mxf_read_packet_old(AVFormatContext *s, AVPacket *pkt) 1725 { 1726 KLVPacket klv; 1727 1728 while (!url_feof(s->pb)) { 1729 if (klv_read_packet(&klv, s->pb) < 0) 1730 return -1; 1731 PRINT_KEY(s, "read packet", klv.key); 1732 av_dlog(s, "size %"PRIu64" offset %#"PRIx64"\n", klv.length, klv.offset); 1733 if (IS_KLV_KEY(klv.key, mxf_encrypted_triplet_key)) { 1734 int res = mxf_decrypt_triplet(s, pkt, &klv); 1735 if (res < 0) { 1736 av_log(s, AV_LOG_ERROR, "invalid encoded triplet\n"); 1737 return -1; 1738 } 1739 return 0; 1740 } 1741 if (IS_KLV_KEY(klv.key, mxf_essence_element_key) || 1742 IS_KLV_KEY(klv.key, mxf_avid_essence_element_key)) { 1743 int index = mxf_get_stream_index(s, &klv); 1744 if (index < 0) { 1745 av_log(s, AV_LOG_ERROR, "error getting stream index %d\n", AV_RB32(klv.key+12)); 1746 goto skip; 1747 } 1748 if (s->streams[index]->discard == AVDISCARD_ALL) 1749 goto skip; 1750 /* check for 8 channels AES3 element */ 1751 if (klv.key[12] == 0x06 && klv.key[13] == 0x01 && klv.key[14] == 0x10) { 1752 if (mxf_get_d10_aes3_packet(s->pb, s->streams[index], pkt, klv.length) < 0) { 1753 av_log(s, AV_LOG_ERROR, "error reading D-10 aes3 frame\n"); 1754 return -1; 1755 } 1756 } else { 1757 int ret = av_get_packet(s->pb, pkt, klv.length); 1758 if (ret < 0) 1759 return ret; 1760 } 1761 pkt->stream_index = index; 1762 pkt->pos = klv.offset; 1763 1764 if (s->streams[index]->codec->codec_type == AVMEDIA_TYPE_VIDEO) 1765 mxf_packet_timestamps(s->priv_data, pkt); /* offset -> EditUnit -> DTS/PTS */ 1766 1767 return 0; 1768 } else 1769 skip: 1770 avio_skip(s->pb, klv.length); 1771 } 1772 return AVERROR_EOF; 1773 } 1774 1775 static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt) 1776 { 1777 MXFContext *mxf = s->priv_data; 1778 int ret, size; 1779 int64_t ret64, pos, next_pos; 1780 AVStream *st; 1781 MXFIndexTable *t; 1782 1783 if (mxf->op != OPAtom) 1784 return mxf_read_packet_old(s, pkt); 1785 1786 /* OPAtom - clip wrapped demuxing */ 1787 st = s->streams[0]; 1788 t = &mxf->index_tables[0]; 1789 1790 if (mxf->current_edit_unit >= st->duration) 1791 return AVERROR_EOF; 1792 1793 if ((ret = mxf_edit_unit_absolute_offset(mxf, t, mxf->current_edit_unit, NULL, &pos, 1)) < 0) 1794 return ret; 1795 1796 /* compute size by finding the next edit unit or the end of the essence container 1797 * not pretty, but it works */ 1798 if ((ret = mxf_edit_unit_absolute_offset(mxf, t, mxf->current_edit_unit + 1, NULL, &next_pos, 0)) < 0 && 1799 (next_pos = mxf_essence_container_end(mxf, t->body_sid)) <= 0) { 1800 av_log(s, AV_LOG_ERROR, "unable to compute the size of the last packet\n"); 1801 return AVERROR_INVALIDDATA; 1802 } 1803 1804 if ((size = next_pos - pos) <= 0) { 1805 av_log(s, AV_LOG_ERROR, "bad size: %i\n", size); 1806 return AVERROR_INVALIDDATA; 1807 } 1808 1809 if ((ret64 = avio_seek(s->pb, pos, SEEK_SET)) < 0) 1810 return ret64; 1811 1812 if ((ret = av_get_packet(s->pb, pkt, size)) != size) 1813 return ret < 0 ? ret : AVERROR_EOF; 1814 1815 if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && t->ptses && 1816 mxf->current_edit_unit >= 0 && mxf->current_edit_unit < t->nb_ptses) { 1817 pkt->dts = mxf->current_edit_unit + t->first_dts; 1818 pkt->pts = t->ptses[mxf->current_edit_unit]; 1819 } 1820 1821 pkt->stream_index = 0; 1822 mxf->current_edit_unit++; 1823 1824 return 0; 1827 1825 } 1828 1826 … … 1852 1850 case IndexTableSegment: 1853 1851 seg = (MXFIndexTableSegment *)mxf->metadata_sets[i]; 1854 if (seg->slice_count)1855 for (j = 0; j < seg->nb_index_entries; j++)1856 av_freep(&seg->slice_offset_entries[j]);1857 av_freep(&seg->slice);1858 av_freep(&seg->element_delta);1859 1852 av_freep(&seg->temporal_offset_entries); 1860 1853 av_freep(&seg->flag_entries); 1861 1854 av_freep(&seg->stream_offset_entries); 1862 av_freep(&seg->slice_offset_entries);1863 1855 break; 1864 1856 default: … … 1871 1863 av_freep(&mxf->aesc); 1872 1864 av_freep(&mxf->local_tags); 1873 av_freep(&mxf->ptses); 1865 1866 for (i = 0; i < mxf->nb_index_tables; i++) { 1867 av_freep(&mxf->index_tables[i].segments); 1868 av_freep(&mxf->index_tables[i].fake_index); 1869 } 1870 av_freep(&mxf->index_tables); 1871 1874 1872 return 0; 1875 1873 } … … 1899 1897 MXFContext* mxf = s->priv_data; 1900 1898 int64_t seekpos; 1901 int index; 1902 1903 if (mxf->d10) { 1899 int ret; 1900 MXFIndexTable *t; 1901 1902 if (mxf->index_tables <= 0) { 1904 1903 if (!s->bit_rate) 1905 1904 return -1; … … 1911 1910 ff_update_cur_dts(s, st, sample_time); 1912 1911 } else { 1913 if (st->nb_index_entries <= 0) 1914 return -1; 1915 1916 index = av_index_search_timestamp(st, sample_time, flags); 1917 1918 av_dlog(s, "stream %d, timestamp %"PRId64", sample %d\n", st->index, sample_time, index); 1919 1920 if (index < 0) { 1921 if (sample_time < st->index_entries[0].timestamp) 1922 index = 0; 1923 else 1924 return -1; 1925 } 1926 1927 seekpos = st->index_entries[index].pos; 1928 av_update_cur_dts(s, st, st->index_entries[index].timestamp); 1929 mxf->current_edit_unit = st->index_entries[index].timestamp; 1930 mxf->current_stream = 0; 1912 t = &mxf->index_tables[0]; 1913 1914 /* clamp above zero, else ff_index_search_timestamp() returns negative 1915 * this also means we allow seeking before the start */ 1916 sample_time = FFMAX(sample_time, 0); 1917 1918 if (t->fake_index) { 1919 /* behave as if we have a proper index */ 1920 if ((sample_time = ff_index_search_timestamp(t->fake_index, t->nb_ptses, sample_time, flags)) < 0) 1921 return sample_time; 1922 } else { 1923 /* no IndexEntryArray (one or more CBR segments) 1924 * make sure we don't seek past the end */ 1925 sample_time = FFMIN(sample_time, st->duration - 1); 1926 } 1927 1928 if ((ret = mxf_edit_unit_absolute_offset(mxf, t, sample_time, &sample_time, &seekpos, 1)) << 0) 1929 return ret; 1930 1931 av_update_cur_dts(s, st, sample_time); 1932 mxf->current_edit_unit = sample_time; 1931 1933 avio_seek(s->pb, seekpos, SEEK_SET); 1932 1934 } -
tests/ref/seek/lavf_mxf_d10
r1c73391d ra9ef21bb 3 3 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 6144 size:150000 4 4 ret: 0 st:-1 flags:1 ts: 1.894167 5 ret: -15 ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:5117952 size:150000 6 6 ret: 0 st: 0 flags:0 ts: 0.800000 7 ret: -17 ret: 0 st: 0 flags:1 dts: 0.800000 pts: 0.800000 pos:4265984 size:150000 8 8 ret: 0 st: 0 flags:1 ts:-0.320000 9 9 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 6144 size:150000 10 10 ret: 0 st: 1 flags:0 ts: 2.560000 11 ret: -111 ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:5117952 size:150000 12 12 ret: 0 st: 1 flags:1 ts: 1.480000 13 ret: -113 ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:5117952 size:150000 14 14 ret: 0 st:-1 flags:0 ts: 0.365002 15 ret: 0 st: 0 flags:1 dts: 0.360000 pts: 0.360000 pos: 6144size:15000015 ret: 0 st: 0 flags:1 dts: 0.360000 pts: 0.360000 pos:1923072 size:150000 16 16 ret: 0 st:-1 flags:1 ts:-0.740831 17 17 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 6144 size:150000 18 18 ret: 0 st: 0 flags:0 ts: 2.160000 19 ret: -119 ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:5117952 size:150000 20 20 ret: 0 st: 0 flags:1 ts: 1.040000 21 ret: -121 ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:5117952 size:150000 22 22 ret: 0 st: 1 flags:0 ts:-0.040000 23 23 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 6144 size:150000 24 24 ret: 0 st: 1 flags:1 ts: 2.840000 25 ret: -125 ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:5117952 size:150000 26 26 ret: 0 st:-1 flags:0 ts: 1.730004 27 ret: -127 ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:5117952 size:150000 28 28 ret: 0 st:-1 flags:1 ts: 0.624171 29 ret: -129 ret: 0 st: 0 flags:1 dts: 0.640000 pts: 0.640000 pos:3414016 size:150000 30 30 ret: 0 st: 0 flags:0 ts:-0.480000 31 31 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 6144 size:150000 32 32 ret: 0 st: 0 flags:1 ts: 2.400000 33 ret: -133 ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:5117952 size:150000 34 34 ret: 0 st: 1 flags:0 ts: 1.320000 35 ret: -135 ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:5117952 size:150000 36 36 ret: 0 st: 1 flags:1 ts: 0.200000 37 ret: 0 st: 0 flags:1 dts: 0.200000 pts: 0.200000 pos: 6144 size:15000037 ret: 0 st: 0 flags:1 dts: 0.200000 pts: 0.200000 pos:1071104 size:150000 38 38 ret: 0 st:-1 flags:0 ts:-0.904994 39 39 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 6144 size:150000 40 40 ret: 0 st:-1 flags:1 ts: 1.989173 41 ret: -141 ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:5117952 size:150000 42 42 ret: 0 st: 0 flags:0 ts: 0.880000 43 ret: -143 ret: 0 st: 0 flags:1 dts: 0.880000 pts: 0.880000 pos:4691968 size:150000 44 44 ret: 0 st: 0 flags:1 ts:-0.240000 45 45 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 6144 size:150000 46 46 ret: 0 st: 1 flags:0 ts: 2.680000 47 ret: -147 ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:5117952 size:150000 48 48 ret: 0 st: 1 flags:1 ts: 1.560000 49 ret: -149 ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:5117952 size:150000 50 50 ret: 0 st:-1 flags:0 ts: 0.460008 51 ret: 0 st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 6144size:15000051 ret: 0 st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:2562048 size:150000 52 52 ret: 0 st:-1 flags:1 ts:-0.645825 53 53 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 6144 size:150000
Note:
See TracChangeset
for help on using the changeset viewer.