Revision 1e77810d libavformat/mov.c

View differences:

libavformat/mov.c
1089 1089
    return 0;
1090 1090
}
1091 1091

  
1092
static void mov_build_index(MOVContext *mov, AVStream *st);
1092
static void mov_build_index(MOVContext *mov, AVStream *st)
1093
{
1094
    MOVStreamContext *sc = st->priv_data;
1095
    offset_t current_offset;
1096
    int64_t current_dts = 0;
1097
    unsigned int stts_index = 0;
1098
    unsigned int stsc_index = 0;
1099
    unsigned int stss_index = 0;
1100
    unsigned int i, j;
1101

  
1102
    if (sc->sample_sizes || st->codec->codec_type == CODEC_TYPE_VIDEO ||
1103
        sc->audio_cid == -2) {
1104
        unsigned int current_sample = 0;
1105
        unsigned int stts_sample = 0;
1106
        unsigned int keyframe, sample_size;
1107
        unsigned int distance = 0;
1108
        int key_off = sc->keyframes && sc->keyframes[0] == 1;
1109

  
1110
        st->nb_frames = sc->sample_count;
1111
        for (i = 0; i < sc->chunk_count; i++) {
1112
            current_offset = sc->chunk_offsets[i];
1113
            if (stsc_index + 1 < sc->sample_to_chunk_sz &&
1114
                i + 1 == sc->sample_to_chunk[stsc_index + 1].first)
1115
                stsc_index++;
1116
            for (j = 0; j < sc->sample_to_chunk[stsc_index].count; j++) {
1117
                if (current_sample >= sc->sample_count) {
1118
                    av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
1119
                    goto out;
1120
                }
1121
                keyframe = !sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index];
1122
                if (keyframe) {
1123
                    distance = 0;
1124
                    if (stss_index + 1 < sc->keyframe_count)
1125
                        stss_index++;
1126
                }
1127
                sample_size = sc->sample_size > 0 ? sc->sample_size : sc->sample_sizes[current_sample];
1128
                dprintf(mov->fc, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
1129
                        "size %d, distance %d, keyframe %d\n", st->index, current_sample,
1130
                        current_offset, current_dts, sample_size, distance, keyframe);
1131
                if(sc->sample_to_chunk[stsc_index].id - 1 == sc->pseudo_stream_id)
1132
                    av_add_index_entry(st, current_offset, current_dts, sample_size, distance,
1133
                                    keyframe ? AVINDEX_KEYFRAME : 0);
1134
                current_offset += sample_size;
1135
                assert(sc->stts_data[stts_index].duration % sc->time_rate == 0);
1136
                current_dts += sc->stts_data[stts_index].duration / sc->time_rate;
1137
                distance++;
1138
                stts_sample++;
1139
                current_sample++;
1140
                if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {
1141
                    stts_sample = 0;
1142
                    stts_index++;
1143
                }
1144
            }
1145
        }
1146
    } else { /* read whole chunk */
1147
        unsigned int chunk_samples, chunk_size, chunk_duration;
1148
        unsigned int frames = 1;
1149
        for (i = 0; i < sc->chunk_count; i++) {
1150
            current_offset = sc->chunk_offsets[i];
1151
            if (stsc_index + 1 < sc->sample_to_chunk_sz &&
1152
                i + 1 == sc->sample_to_chunk[stsc_index + 1].first)
1153
                stsc_index++;
1154
            chunk_samples = sc->sample_to_chunk[stsc_index].count;
1155
            /* get chunk size, beware of alaw/ulaw/mace */
1156
            if (sc->samples_per_frame > 0 &&
1157
                (chunk_samples * sc->bytes_per_frame % sc->samples_per_frame == 0)) {
1158
                if (sc->samples_per_frame < 1024)
1159
                    chunk_size = chunk_samples * sc->bytes_per_frame / sc->samples_per_frame;
1160
                else {
1161
                    chunk_size = sc->bytes_per_frame;
1162
                    frames = chunk_samples / sc->samples_per_frame;
1163
                    chunk_samples = sc->samples_per_frame;
1164
                }
1165
            } else if (sc->sample_size > 1 || st->codec->bits_per_sample == 8) {
1166
                chunk_size = chunk_samples * sc->sample_size;
1167
            } else {
1168
                av_log(mov->fc, AV_LOG_ERROR, "could not determine chunk size, report problem\n");
1169
                goto out;
1170
            }
1171
            for (j = 0; j < frames; j++) {
1172
                av_add_index_entry(st, current_offset, current_dts, chunk_size, 0, AVINDEX_KEYFRAME);
1173
                /* get chunk duration */
1174
                chunk_duration = 0;
1175
                while (chunk_samples > 0) {
1176
                    if (chunk_samples < sc->stts_data[stts_index].count) {
1177
                        chunk_duration += sc->stts_data[stts_index].duration * chunk_samples;
1178
                        sc->stts_data[stts_index].count -= chunk_samples;
1179
                        break;
1180
                    } else {
1181
                        chunk_duration += sc->stts_data[stts_index].duration * chunk_samples;
1182
                        chunk_samples -= sc->stts_data[stts_index].count;
1183
                        if (stts_index + 1 < sc->stts_count)
1184
                            stts_index++;
1185
                    }
1186
                }
1187
                current_offset += sc->bytes_per_frame;
1188
                dprintf(mov->fc, "AVIndex stream %d, chunk %d, offset %"PRIx64", dts %"PRId64", size %d, "
1189
                        "duration %d\n", st->index, i, current_offset, current_dts, chunk_size, chunk_duration);
1190
                assert(chunk_duration % sc->time_rate == 0);
1191
                current_dts += chunk_duration / sc->time_rate;
1192
            }
1193
        }
1194
    }
1195
 out:
1196
    /* adjust sample count to avindex entries */
1197
    sc->sample_count = st->nb_index_entries;
1198
}
1093 1199

  
1094 1200
static int mov_read_trak(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1095 1201
{
......
1435 1541
    return score;
1436 1542
}
1437 1543

  
1438
static void mov_build_index(MOVContext *mov, AVStream *st)
1439
{
1440
    MOVStreamContext *sc = st->priv_data;
1441
    offset_t current_offset;
1442
    int64_t current_dts = 0;
1443
    unsigned int stts_index = 0;
1444
    unsigned int stsc_index = 0;
1445
    unsigned int stss_index = 0;
1446
    unsigned int i, j;
1447

  
1448
    if (sc->sample_sizes || st->codec->codec_type == CODEC_TYPE_VIDEO ||
1449
        sc->audio_cid == -2) {
1450
        unsigned int current_sample = 0;
1451
        unsigned int stts_sample = 0;
1452
        unsigned int keyframe, sample_size;
1453
        unsigned int distance = 0;
1454
        int key_off = sc->keyframes && sc->keyframes[0] == 1;
1455

  
1456
        st->nb_frames = sc->sample_count;
1457
        for (i = 0; i < sc->chunk_count; i++) {
1458
            current_offset = sc->chunk_offsets[i];
1459
            if (stsc_index + 1 < sc->sample_to_chunk_sz &&
1460
                i + 1 == sc->sample_to_chunk[stsc_index + 1].first)
1461
                stsc_index++;
1462
            for (j = 0; j < sc->sample_to_chunk[stsc_index].count; j++) {
1463
                if (current_sample >= sc->sample_count) {
1464
                    av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
1465
                    goto out;
1466
                }
1467
                keyframe = !sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index];
1468
                if (keyframe) {
1469
                    distance = 0;
1470
                    if (stss_index + 1 < sc->keyframe_count)
1471
                        stss_index++;
1472
                }
1473
                sample_size = sc->sample_size > 0 ? sc->sample_size : sc->sample_sizes[current_sample];
1474
                dprintf(mov->fc, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
1475
                        "size %d, distance %d, keyframe %d\n", st->index, current_sample,
1476
                        current_offset, current_dts, sample_size, distance, keyframe);
1477
                if(sc->sample_to_chunk[stsc_index].id - 1 == sc->pseudo_stream_id)
1478
                    av_add_index_entry(st, current_offset, current_dts, sample_size, distance,
1479
                                    keyframe ? AVINDEX_KEYFRAME : 0);
1480
                current_offset += sample_size;
1481
                assert(sc->stts_data[stts_index].duration % sc->time_rate == 0);
1482
                current_dts += sc->stts_data[stts_index].duration / sc->time_rate;
1483
                distance++;
1484
                stts_sample++;
1485
                current_sample++;
1486
                if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {
1487
                    stts_sample = 0;
1488
                    stts_index++;
1489
                }
1490
            }
1491
        }
1492
    } else { /* read whole chunk */
1493
        unsigned int chunk_samples, chunk_size, chunk_duration;
1494
        unsigned int frames = 1;
1495
        for (i = 0; i < sc->chunk_count; i++) {
1496
            current_offset = sc->chunk_offsets[i];
1497
            if (stsc_index + 1 < sc->sample_to_chunk_sz &&
1498
                i + 1 == sc->sample_to_chunk[stsc_index + 1].first)
1499
                stsc_index++;
1500
            chunk_samples = sc->sample_to_chunk[stsc_index].count;
1501
            /* get chunk size, beware of alaw/ulaw/mace */
1502
            if (sc->samples_per_frame > 0 &&
1503
                (chunk_samples * sc->bytes_per_frame % sc->samples_per_frame == 0)) {
1504
                if (sc->samples_per_frame < 1024)
1505
                    chunk_size = chunk_samples * sc->bytes_per_frame / sc->samples_per_frame;
1506
                else {
1507
                    chunk_size = sc->bytes_per_frame;
1508
                    frames = chunk_samples / sc->samples_per_frame;
1509
                    chunk_samples = sc->samples_per_frame;
1510
                }
1511
            } else if (sc->sample_size > 1 || st->codec->bits_per_sample == 8) {
1512
                chunk_size = chunk_samples * sc->sample_size;
1513
            } else {
1514
                av_log(mov->fc, AV_LOG_ERROR, "could not determine chunk size, report problem\n");
1515
                goto out;
1516
            }
1517
            for (j = 0; j < frames; j++) {
1518
                av_add_index_entry(st, current_offset, current_dts, chunk_size, 0, AVINDEX_KEYFRAME);
1519
                /* get chunk duration */
1520
                chunk_duration = 0;
1521
                while (chunk_samples > 0) {
1522
                    if (chunk_samples < sc->stts_data[stts_index].count) {
1523
                        chunk_duration += sc->stts_data[stts_index].duration * chunk_samples;
1524
                        sc->stts_data[stts_index].count -= chunk_samples;
1525
                        break;
1526
                    } else {
1527
                        chunk_duration += sc->stts_data[stts_index].duration * chunk_samples;
1528
                        chunk_samples -= sc->stts_data[stts_index].count;
1529
                        if (stts_index + 1 < sc->stts_count)
1530
                            stts_index++;
1531
                    }
1532
                }
1533
                current_offset += sc->bytes_per_frame;
1534
                dprintf(mov->fc, "AVIndex stream %d, chunk %d, offset %"PRIx64", dts %"PRId64", size %d, "
1535
                        "duration %d\n", st->index, i, current_offset, current_dts, chunk_size, chunk_duration);
1536
                assert(chunk_duration % sc->time_rate == 0);
1537
                current_dts += chunk_duration / sc->time_rate;
1538
            }
1539
        }
1540
    }
1541
 out:
1542
    /* adjust sample count to avindex entries */
1543
    sc->sample_count = st->nb_index_entries;
1544
}
1545

  
1546 1544
static int mov_read_header(AVFormatContext *s, AVFormatParameters *ap)
1547 1545
{
1548 1546
    MOVContext *mov = s->priv_data;

Also available in: Unified diff