Revision 5cd62665

View differences:

libavcodec/avcodec.h
1080 1080
     * - decoding: unused
1081 1081
     */
1082 1082
    int inter_quant_bias;
1083

  
1084
    /**
1085
     * color table ID.
1086
     * - encoding: unused.
1087
     * - decoding: which clrtable should be used for 8bit RGB images
1088
     *             table have to be stored somewhere FIXME
1089
     */
1090
    int color_table_id;
1083 1091
    
1084 1092
} AVCodecContext;
1085 1093

  
libavformat/mov.c
76 76
           (tag >> 16) & 0xff,
77 77
           (tag >> 24) & 0xff,
78 78
           (unsigned int)offset,
79
           (unsigned int)size);
79
	   (unsigned int)size);
80
    assert((unsigned int)size < 0x7fffffff);// catching errors
80 81
}
81 82
#endif
82 83

  
......
112 113
    { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'c', ' ') }, /* DV NTSC */
113 114
    { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'c', 'p') }, /* DV PAL */
114 115
/*    { CODEC_ID_DVVIDEO, MKTAG('A', 'V', 'd', 'v') }, *//* AVID dv */
115
    { 0, 0 }, 
116
    { 0, 0 },
116 117
};
117 118

  
118 119
static const CodecTag mov_audio_tags[] = {
119 120
/*    { CODEC_ID_PCM_S16BE, MKTAG('N', 'O', 'N', 'E') }, *//* uncompressed */
120 121
    { CODEC_ID_PCM_S16BE, MKTAG('t', 'w', 'o', 's') }, /* 16 bits */
121 122
    { CODEC_ID_PCM_S8, MKTAG('t', 'w', 'o', 's') }, /* 8 bits */
122
    { CODEC_ID_PCM_U8, 0x20776172 }, /* 8 bits unsigned */
123
    { CODEC_ID_PCM_U8, MKTAG('r', 'a', 'w', ' ') }, /* 8 bits unsigned */
123 124
    { CODEC_ID_PCM_S16LE, MKTAG('s', 'o', 'w', 't') }, /*  */
124 125
    { CODEC_ID_PCM_MULAW, MKTAG('u', 'l', 'a', 'w') }, /*  */
125 126
    { CODEC_ID_PCM_ALAW, MKTAG('a', 'l', 'a', 'w') }, /*  */
......
148 149
    long id;
149 150
} MOV_sample_to_chunk_tbl;
150 151

  
152
typedef struct {
153
    uint8_t  version;
154
    uint32_t flags; // 24bit
155

  
156
    /* 0x03 ESDescrTag */
157
    uint16_t es_id;
158
#define MP4ODescrTag			0x01
159
#define MP4IODescrTag			0x02
160
#define MP4ESDescrTag			0x03
161
#define MP4DecConfigDescrTag		0x04
162
#define MP4DecSpecificDescrTag		0x05
163
#define MP4SLConfigDescrTag		0x06
164
#define MP4ContentIdDescrTag		0x07
165
#define MP4SupplContentIdDescrTag	0x08
166
#define MP4IPIPtrDescrTag		0x09
167
#define MP4IPMPPtrDescrTag		0x0A
168
#define MP4IPMPDescrTag			0x0B
169
#define MP4RegistrationDescrTag		0x0D
170
#define MP4ESIDIncDescrTag		0x0E
171
#define MP4ESIDRefDescrTag		0x0F
172
#define MP4FileIODescrTag		0x10
173
#define MP4FileODescrTag		0x11
174
#define MP4ExtProfileLevelDescrTag	0x13
175
#define MP4ExtDescrTagsStart		0x80
176
#define MP4ExtDescrTagsEnd		0xFE
177
    uint8_t  stream_priority;
178

  
179
    /* 0x04 DecConfigDescrTag */
180
    uint8_t  object_type_id;
181
    uint8_t  stream_type;
182
    /* XXX: really streamType is
183
     * only 6bit, followed by:
184
     * 1bit  upStream
185
     * 1bit  reserved
186
     */
187
    uint32_t buffer_size_db; // 24
188
    uint32_t max_bitrate;
189
    uint32_t avg_bitrate;
190

  
191
    /* 0x05 DecSpecificDescrTag */
192
    uint8_t  decoder_cfg_len;
193
    uint8_t *decoder_cfg;
194

  
195
    /* 0x06 SLConfigDescrTag */
196
    uint8_t  sl_config_len;
197
    uint8_t *sl_config;
198
} MOV_esds_t;
199

  
151 200
typedef struct MOVStreamContext {
152 201
    int ffindex; /* the ffmpeg stream id */
153 202
    int is_ff_stream; /* Is this stream presented to ffmpeg ? i.e. is this an audio or video stream ? */
......
160 209
    long sample_size;
161 210
    long sample_count;
162 211
    long *sample_sizes;
163
    long time_scale;
212
    int time_scale;
164 213
    long current_sample;
165 214
    long left_in_chunk; /* how many samples before next chunk */
166 215
    /* specific MPEG4 header which is added at the beginning of the stream */
167 216
    int header_len;
217
    MOV_esds_t esds;
168 218
    uint8_t *header_data;
169 219
} MOVStreamContext;
170 220

  
171 221
typedef struct MOVContext {
172 222
    int mp4; /* set to 1 as soon as we are sure that the file is an .mp4 file (even some header parsing depends on this) */
173 223
    AVFormatContext *fc;
174
    long time_scale;
224
    int time_scale;
225
    int duration; /* duration of the longest track */
175 226
    int found_moov; /* when both 'moov' and 'mdat' sections has been found */
176 227
    int found_mdat; /* we suppose we have enough data to read the file */
177 228
    int64_t mdat_size;
......
181 232
     * but we need the info to be able to skip data from those streams in the 'mdat' section
182 233
     */
183 234
    MOVStreamContext *streams[MAX_STREAMS];
184
    
235

  
185 236
    int64_t next_chunk_offset;
186
    int partial; /* != 0 : there is still to read in the current chunk (=id of the stream + 1) */
237
    MOVStreamContext *partial; /* != 0 : there is still to read in the current chunk */
187 238
} MOVContext;
188 239

  
189 240

  
......
209 260
    uint32_t type;
210 261
    mov_parse_function func;
211 262
} MOVParseTableEntry;
263
static const MOVParseTableEntry mov_default_parse_table[];
212 264

  
213 265
static int parse_leaf(const MOVParseTableEntry *parse_table, ByteIOContext *pb, uint32_t atom_type, int64_t atom_offset, int64_t atom_size, void *param)
214 266
{
......
234 286
    print_atom("default", atom_type, atom_offset, atom_size);
235 287
    debug_indent++;
236 288
#endif
237
    
289

  
238 290
    offset = atom_offset;
239 291

  
240 292
    if(atom_size < 0)
241 293
        atom_size = 0x0FFFFFFFFFFFFFFF;
242
    while((total_size < atom_size) && !url_feof(pb) && !err) {
294
    while(((total_size + 8) < atom_size) && !url_feof(pb) && !err) {
243 295
        size=atom_size;
244 296
        type=0L;
245 297
        if(atom_size >= 8) {
246
            size = get_be32(pb);
298
	    size = get_be32(pb);
247 299
            type = get_le32(pb);
248 300
        }
249
        total_size += 8;
250
        offset+=8;
251
//        printf("type: %08lx  sz: %08lx", type, size);
301
	total_size += 8;
302
        offset += 8;
303
	//printf("type: %08x  %.4s  sz: %Lx  %Lx   %Lx\n", type, (char*)&type, size, atom_size, total_size);
252 304
        if(size == 1) { /* 64 bit extended size */
253
            size = get_be64(pb);
305
            size = get_be64(pb) - 8;
254 306
            offset+=8;
255 307
            total_size+=8;
256
            size-=8;
257 308
        }
258
        if(size == 0)
259
            size = atom_size - total_size;
260
        size-=8;
261
        for(i=0; parse_table[i].type != 0L && parse_table[i].type != type; i++);
262
        
309
	if(size == 0) {
310
	    size = atom_size - total_size;
311
	    if (size <= 8)
312
                break;
313
	}
314
	for (i=0; parse_table[i].type != 0L && parse_table[i].type != type; i++)
315
	    /* empty */;
316

  
317
        size -= 8;
263 318
//        printf(" i=%ld\n", i);
264 319
	if (parse_table[i].type == 0) { /* skip leaf atoms data */
265 320
//            url_seek(pb, atom_offset+atom_size, SEEK_SET);
......
274 329
        total_size+=size;
275 330
    }
276 331

  
332
    if (!err && total_size < atom_size && atom_size < 0x7ffff) {
333
	printf("RESET  %Ld  %Ld  err:%d\n", atom_size, total_size, err);
334
        url_fskip(pb, atom_size - total_size);
335
    }
336

  
277 337
#ifdef DEBUG
278 338
    debug_indent--;
279 339
#endif
280 340
    return err;
281 341
}
282 342

  
343
static int parse_ctab(const MOVParseTableEntry *parse_table, ByteIOContext *pb, uint32_t atom_type, int64_t atom_offset, int64_t atom_size, void *param)
344
{
345
    url_fskip(pb, atom_size); // for now
346
    return 0;
347
}
348

  
283 349
static int parse_mvhd(const MOVParseTableEntry *parse_table, ByteIOContext *pb, uint32_t atom_type, int64_t atom_offset, int64_t atom_size, void *param)
284 350
{
285 351
    MOVContext *c;
......
295 361
    get_be32(pb); /* modification time */
296 362
    c->time_scale = get_be32(pb); /* time scale */
297 363
#ifdef DEBUG
298
    printf("time scale = %li\n", c->time_scale);
364
    printf("time scale = %i\n", c->time_scale);
299 365
#endif
300
    get_be32(pb); /* duration */
366
    c->duration = get_be32(pb); /* duration */
301 367
    get_be32(pb); /* preferred scale */
302
    
368

  
303 369
    get_be16(pb); /* preferred volume */
304 370

  
305 371
    url_fskip(pb, 10); /* reserved */
......
398 464
    st = av_new_stream(c->fc, c->fc->nb_streams);
399 465
    if (!st) return -2;
400 466
    sc = av_malloc(sizeof(MOVStreamContext));
467
    memset(sc, 0, sizeof(MOVStreamContext));
401 468
    sc->sample_to_chunk_index = -1;
402 469
    st->priv_data = sc;
403 470
    st->codec.codec_type = CODEC_TYPE_MOV_OTHER;
471
    st->time_length = (c->duration * 1000) / c->time_scale; // time in miliseconds
404 472
    c->streams[c->fc->nb_streams-1] = sc;
405 473
    return parse_default(parse_table, pb, atom_type, atom_offset, atom_size, param);
406 474
}
......
415 483

  
416 484
    c = (MOVContext *)param;
417 485
    st = c->fc->streams[c->fc->nb_streams-1];
418
    
486

  
419 487
    get_byte(pb); /* version */
420 488

  
421 489
    get_byte(pb); get_byte(pb);
......
431 499
    get_be32(pb); /* modification time */
432 500
    st->id = (int)get_be32(pb); /* track id (NOT 0 !)*/
433 501
    get_be32(pb); /* reserved */
434
    get_be32(pb); /* duration */
502
    st->time_length = get_be32(pb) * 1000 / c->time_scale; /* duration */
435 503
    get_be32(pb); /* reserved */
436 504
    get_be32(pb); /* reserved */
437
    
505

  
438 506
    get_be16(pb); /* layer */
439 507
    get_be16(pb); /* alternate group */
440 508
    get_be16(pb); /* volume */
......
459 527

  
460 528
    c = (MOVContext *)param;
461 529
    st = c->fc->streams[c->fc->nb_streams-1];
462
    
530

  
463 531
    get_byte(pb); /* version */
464 532

  
465 533
    get_byte(pb); get_byte(pb);
......
471 539
    c->streams[c->total_streams]->time_scale = get_be32(pb);
472 540

  
473 541
#ifdef DEBUG
474
    printf("track[%i].time_scale = %li\n", c->fc->nb_streams-1, c->streams[c->total_streams]->time_scale); /* time scale */
542
    printf("track[%i].time_scale = %i\n", c->fc->nb_streams-1, c->streams[c->total_streams]->time_scale); /* time scale */
475 543
#endif
476 544
    get_be32(pb); /* duration */
477 545

  
478 546
    get_be16(pb); /* language */
479 547
    get_be16(pb); /* quality */
480
    
548

  
481 549
    return 0;
482 550
}
483 551

  
......
584 652
        }
585 653
    }
586 654
#endif
587
    
655

  
588 656
    return 0;
589 657
}
590 658

  
591 659
static int mp4_read_descr_len(ByteIOContext *pb)
592 660
{
593
    int c, len, count;
594

  
595
    len = 0;
596
    count = 0;
661
    int len = 0;
662
    int count = 0;
597 663
    for(;;) {
598
        c = get_byte(pb);
599
        len = (len << 7) | (c & 0x7f);
664
        int c = get_byte(pb);
665
	len = (len << 7) | (c & 0x7f);
600 666
        if ((c & 0x80) == 0)
601 667
            break;
602 668
        if (++count == 4)
......
616 682
    return len;
617 683
}
618 684

  
685
static inline unsigned int get_be24(ByteIOContext *s)
686
{
687
    unsigned int val;
688
    val = get_byte(s) << 16;
689
    val |= get_byte(s) << 8;
690
    val |= get_byte(s);
691
    return val;
692
}
693

  
694
static int parse_esds(const MOVParseTableEntry *parse_table, ByteIOContext *pb, uint32_t atom_type, int64_t atom_offset, int64_t atom_size, void *param)
695
{
696

  
697
    int64_t start_pos = url_ftell(pb);
698
    MOVContext *c = (MOVContext *)param;
699
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
700
    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
701
    int tag, len;
702
#ifdef DEBUG
703
    print_atom("esds", atom_type, atom_offset, atom_size);
704
#endif
705

  
706
    /* Well, broken but suffisant for some MP4 streams */
707
    get_be32(pb); /* version + flags */
708
    len = mp4_read_descr(pb, &tag);
709
    if (tag == MP4ESDescrTag) {
710
	get_be16(pb); /* ID */
711
	get_byte(pb); /* priority */
712
    } else
713
	get_be16(pb); /* ID */
714

  
715
    len = mp4_read_descr(pb, &tag);
716
    if (tag == MP4DecConfigDescrTag) {
717
	sc->esds.object_type_id = get_byte(pb);
718
	sc->esds.stream_type = get_be24(pb);
719
	sc->esds.max_bitrate = get_be32(pb);
720
	sc->esds.avg_bitrate = get_be32(pb);
721

  
722
	len = mp4_read_descr(pb, &tag);
723
	printf("LEN %d  TAG %d  m:%d a:%d\n", len, tag, sc->esds.max_bitrate, sc->esds.avg_bitrate);
724
	if (tag == MP4DecSpecificDescrTag) {
725
#ifdef DEBUG
726
	    printf("Specific MPEG4 header len=%d\n", len);
727
#endif
728
	    sc->header_data = av_mallocz(len);
729
	    if (sc->header_data) {
730
		get_buffer(pb, sc->header_data, len);
731
		sc->header_len = len;
732
	    }
733
	}
734
    }
735
    /* in any case, skip garbage */
736
    url_fskip(pb, (atom_size - 8) - ((url_ftell(pb) - start_pos)));
737
    return 0;
738
}
739

  
619 740
static int parse_stsd(const MOVParseTableEntry *parse_table, ByteIOContext *pb, uint32_t atom_type, int64_t atom_offset, int64_t atom_size, void *param)
620 741
{
621 742
    MOVContext *c;
622
    int entries, size, samp_sz, frames_per_sample, id;
743
    int entries, size, frames_per_sample, id;
623 744
    uint32_t format;
624 745
    AVStream *st;
625 746
    MOVStreamContext *sc;
......
636 757
    entries = get_be32(pb);
637 758

  
638 759
    while(entries--) {
639
        size = get_be32(pb); /* size */
760
	size = get_be32(pb); /* size */
640 761
        format = get_le32(pb); /* data format */
641
        
762

  
642 763
        get_be32(pb); /* reserved */
643 764
        get_be16(pb); /* reserved */
644 765
        get_be16(pb); /* index */
......
652 773
                st->codec.codec_type = codec->type;
653 774
        }
654 775
#ifdef DEBUG
655
        printf("size=%d 4CC= %c%c%c%c codec_type=%d\n", 
656
               size, 
776
        printf("size=%d 4CC= %c%c%c%c codec_type=%d\n",
777
               size,
657 778
               (format >> 0) & 0xff,
658 779
               (format >> 8) & 0xff,
659 780
               (format >> 16) & 0xff,
660 781
               (format >> 24) & 0xff,
661 782
               st->codec.codec_type);
662 783
#endif
784
	st->codec.codec_tag = format;
663 785
        if(st->codec.codec_type==CODEC_TYPE_VIDEO) {
664
            st->codec.codec_tag = format;
665 786
            st->codec.codec_id = codec_get_id(mov_video_tags, format);
666 787
            get_be16(pb); /* version */
667 788
            get_be16(pb); /* revision level */
......
681 802
            get_be32(pb); /* horiz resolution */
682 803
            get_be32(pb); /* vert resolution */
683 804
            get_be32(pb); /* data size, always 0 */
684
            frames_per_sample = get_be16(pb); /* frame per samples */
805
            frames_per_sample = get_be16(pb); /* frames per samples */
685 806
#ifdef DEBUG
686 807
	    printf("frames/samples = %d\n", frames_per_sample);
687 808
#endif
688
            url_fskip(pb, 32); /* codec name */
809
	    get_buffer(pb, st->codec.codec_name, 32); /* codec name */
810

  
811
	    st->codec.bits_per_sample = get_be16(pb); /* depth */
812
            st->codec.color_table_id = get_be16(pb); /* colortable id */
689 813

  
690
            get_be16(pb); /* depth */
691
            get_be16(pb); /* colortable id */
692
            
693 814
            st->codec.frame_rate      = 25;
694 815
            st->codec.frame_rate_base = 1;
695
            
816

  
696 817
            size -= (16+8*4+2+32+2*2);
697
            while (size >= 8) {
818
#if 0
819
	    while (size >= 8) {
698 820
                int atom_size, atom_type;
699 821
                int64_t start_pos;
700
                
822

  
701 823
                atom_size = get_be32(pb);
702 824
                atom_type = get_le32(pb);
703
                size -= 8;
825
		size -= 8;
826
                printf("NEWSIZE %d\n", size);
704 827
#ifdef DEBUG
705
                printf("VIDEO: atom_type=%c%c%c%c atom_size=%d size_left=%d\n", 
828
                printf("VIDEO: atom_type=%c%c%c%c atom_size=%d size_left=%d\n",
706 829
                       (atom_type >> 0) & 0xff,
707 830
                       (atom_type >> 8) & 0xff,
708 831
                       (atom_type >> 16) & 0xff,
......
728 851
                            /* MP4DecConfigDescrTag */
729 852
                            get_byte(pb); /* objectTypeId */
730 853
                            get_be32(pb); /* streamType + buffer size */
731
                            get_be32(pb); /* max bit rate */
854
			    get_be32(pb); /* max bit rate */
732 855
                            get_be32(pb); /* avg bit rate */
733 856
                            len = mp4_read_descr(pb, &tag);
734 857
                            if (tag != 0x05)
......
740 863
                            sc->header_data = av_mallocz(len);
741 864
                            if (sc->header_data) {
742 865
                                get_buffer(pb, sc->header_data, len);
743
                                sc->header_len = len;
866
				sc->header_len = len;
744 867
                            }
745 868
                        }
746 869
                        /* in any case, skip garbage */
......
749 872
                default:
750 873
                    break;
751 874
                }
752
            fail:
753
                url_fskip(pb, (atom_size - 8) - 
754
                          ((url_ftell(pb) - start_pos)));
755
                size -= atom_size - 8;
756
            }
875
	    fail:
876
                printf("ATOMENEWSIZE %d   %d\n", atom_size, url_ftell(pb) - start_pos);
877
		if (atom_size > 8) {
878
		    url_fskip(pb, (atom_size - 8) -
879
			      ((url_ftell(pb) - start_pos)));
880
		    size -= atom_size - 8;
881
		    printf("NEWSIZE %d\n", size);
882
		}
883
	    }
757 884
            if (size > 0) {
758 885
                /* unknown extension */
759 886
                url_fskip(pb, size);
760 887
            }
761
        } else {
762
            st->codec.codec_tag = format;
763

  
888
#else
889
	    parse_default(mov_default_parse_table, pb, 0L, 0LL, size, param);
890
#endif
891
	} else {
764 892
            get_be16(pb); /* version */
765 893
            get_be16(pb); /* revision level */
766 894
            get_be32(pb); /* vendor */
767 895

  
768 896
            st->codec.channels = get_be16(pb);/* channel count */
769
            samp_sz = get_be16(pb); /* sample size */
770
#ifdef DEBUG
771
            if(samp_sz != 16)
772
                puts("!!! stsd: audio sample size is not 16 bit !");
773
#endif            
774
            st->codec.codec_id = codec_get_id(mov_audio_tags, format);
775
            /* handle specific s8 codec */
776
            if (st->codec.codec_id == CODEC_ID_PCM_S16BE && samp_sz == 8)
777
            st->codec.codec_id = CODEC_ID_PCM_S8;
897
	    st->codec.bits_per_sample = get_be16(pb); /* sample size */
778 898

  
899
	    st->codec.codec_id = codec_get_id(mov_audio_tags, format);
900
            /* handle specific s8 codec */
779 901
            get_be16(pb); /* compression id = 0*/
780 902
            get_be16(pb); /* packet size = 0 */
781
            
903

  
782 904
            st->codec.sample_rate = ((get_be32(pb) >> 16));
783
            st->codec.bit_rate = 0;
784
#if 0
785 905

  
786
            get_be16(pb); get_be16(pb); /*  */
787
            get_be16(pb); /*  */
788
            get_be16(pb); /*  */
789
            get_be16(pb); /*  */
790
            get_be16(pb); /*  */
791
#endif            
792
            if(size > 16)
793
                url_fskip(pb, size-(16+20));
906
	    if (st->codec.codec_id == CODEC_ID_PCM_S16BE) {
907
		if (st->codec.bits_per_sample == 8)
908
		    st->codec.codec_id = CODEC_ID_PCM_S8;
909
                st->codec.bit_rate = st->codec.sample_rate;
910
	    }
911
	    get_be32(pb); /* samples per packet */
912
	    get_be32(pb); /* bytes per packet */
913
            get_be32(pb); /* bytes per frame */
914
            get_be32(pb); /* bytes per sample */
915

  
916
	    //if (size > 16) url_fskip(pb, size-(16+20));
917
#if 1
918
	    if (size >= 44 + 8) {
919
                int fcc;
920
		st->codec.extradata_size = get_be32(pb) - 8;
921
		fcc = get_le32(pb); // evaw
922
		//printf("%x  %.4s  %d\n", fcc, (char*)&fcc, st->codec.extradata_size);
923
		st->codec.extradata = av_mallocz(st->codec.extradata_size);
924
                get_buffer(pb, st->codec.extradata, st->codec.extradata_size);
925
		url_fskip(pb, size-(16 + 20 + 16 + 8 + st->codec.extradata_size));
926
	    }
927
            else
928
		url_fskip(pb, size-(16 + 20 + 16));
929
#else
930
	    parse_default(mov_default_parse_table, pb, 0L, 0LL, size - (16 + 20 + 16 + 8), param);
931
#endif
794 932
        }
795 933
    }
796 934
/*
......
817 955
    c = (MOVContext *)param;
818 956
    st = c->fc->streams[c->fc->nb_streams-1];
819 957
    sc = (MOVStreamContext *)st->priv_data;
820
    
958

  
821 959
    get_byte(pb); /* version */
822 960
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
823 961

  
......
856 994
    c = (MOVContext *)param;
857 995
    st = c->fc->streams[c->fc->nb_streams-1];
858 996
    sc = (MOVStreamContext *)st->priv_data;
859
    
997

  
860 998
    get_byte(pb); /* version */
861 999
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
862 1000

  
......
889 1027
    c = (MOVContext *)param;
890 1028
    st = c->fc->streams[c->fc->nb_streams-1];
891 1029
    sc = (MOVStreamContext *)st->priv_data;
892
    
1030

  
893 1031
    get_byte(pb); /* version */
894 1032
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
895
    
1033

  
896 1034
    sc->sample_size = get_be32(pb);
897 1035
    entries = get_be32(pb);
898 1036
    sc->sample_count = entries;
......
978 1116
        return -1;
979 1117
    moov_len = get_be32(pb); /* uncompressed size */
980 1118
    cmov_len = atom_size - 6 * 4;
981
    
1119

  
982 1120
    cmov_data = av_malloc(cmov_len);
983 1121
    if (!cmov_data)
984 1122
        return -1;
......
1013 1151
{ MKTAG( 'd', 'i', 'n', 'f' ), parse_default },
1014 1152
{ MKTAG( 'd', 'r', 'e', 'f' ), parse_leaf },
1015 1153
{ MKTAG( 's', 't', 'd', 'p' ), parse_default },
1016
{ MKTAG( 'e', 's', 'd', 's' ), parse_default },
1017 1154
{ MKTAG( 'e', 'd', 't', 's' ), parse_default },
1018 1155
{ MKTAG( 'e', 'l', 's', 't' ), parse_leaf },
1019 1156
{ MKTAG( 'u', 'u', 'i', 'd' ), parse_default },
......
1067 1204
{ MKTAG( 's', 's', 'r', 'c' ), parse_leaf },
1068 1205
{ MKTAG( 't', 'c', 'm', 'd' ), parse_leaf },
1069 1206
{ MKTAG( 'w', 'i', 'd', 'e' ), parse_wide }, /* place holder */
1207
{ MKTAG( 'c', 't', 'a', 'b' ), parse_ctab },
1208
{ MKTAG( 'e', 's', 'd', 's' ), parse_esds },
1070 1209
#ifdef CONFIG_ZLIB
1071 1210
{ MKTAG( 'c', 'm', 'o', 'v' ), parse_cmov },
1072 1211
#else
......
1080 1219
    if(sc) {
1081 1220
        av_free(sc->chunk_offsets);
1082 1221
        av_free(sc->sample_to_chunk);
1222
        av_free(sc->sample_sizes);
1083 1223
        av_free(sc->header_data);
1084 1224
        av_free(sc);
1085 1225
    }
1086 1226
}
1087 1227

  
1088
static uint32_t to_tag(uint8_t *buf)
1228
static inline uint32_t to_tag(uint8_t *buf)
1089 1229
{
1090 1230
    return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
1091 1231
}
1092 1232

  
1093
static uint32_t to_be32(uint8_t *buf)
1233
static inline uint32_t to_be32(uint8_t *buf)
1094 1234
{
1095 1235
    return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
1096 1236
}
......
1206 1346
    MOVStreamContext *sc;
1207 1347
    int64_t offset = 0x0FFFFFFFFFFFFFFF;
1208 1348
    int i;
1209
    int st_id = 0, size;
1349
    int size;
1210 1350
    size = 0x0FFFFFFF;
1211
    
1351

  
1212 1352
#ifdef MOV_SPLIT_CHUNKS
1213 1353
    if (mov->partial) {
1214
        
1354

  
1215 1355
        int idx;
1216 1356

  
1217
        st_id = mov->partial - 1;
1218
        idx = mov->streams[st_id]->sample_to_chunk_index;
1357
	sc = mov->partial;
1358
	idx = sc->sample_to_chunk_index;
1359

  
1219 1360
        if (idx < 0) return 0;
1220
        size = mov->streams[st_id]->sample_sizes[mov->streams[st_id]->current_sample];
1361
	size = sc->sample_sizes[sc->current_sample];
1221 1362

  
1222
        mov->streams[st_id]->current_sample++;
1223
        mov->streams[st_id]->left_in_chunk--;
1363
        sc->current_sample++;
1364
        sc->left_in_chunk--;
1224 1365

  
1225
        if(mov->streams[st_id]->left_in_chunk <= 0)
1366
        if (sc->left_in_chunk <= 0)
1226 1367
            mov->partial = 0;
1227 1368
        offset = mov->next_chunk_offset;
1228 1369
        /* extract the sample */
......
1232 1373
#endif
1233 1374

  
1234 1375
again:
1376
    sc = 0;
1235 1377
    for(i=0; i<mov->total_streams; i++) {
1236
        if((mov->streams[i]->next_chunk < mov->streams[i]->chunk_count)
1237
        && (mov->streams[i]->chunk_offsets[mov->streams[i]->next_chunk] < offset)) {
1238
            st_id = i;
1239
            offset = mov->streams[i]->chunk_offsets[mov->streams[i]->next_chunk];
1378
	MOVStreamContext *msc = mov->streams[i];
1379
	//printf("MOCHUNK %ld  %d   %p  pos:%Ld\n", mov->streams[i]->next_chunk, mov->total_streams, mov->streams[i], url_ftell(&s->pb));
1380
        if ((msc->next_chunk < msc->chunk_count) && msc->next_chunk >= 0
1381
	   && (msc->chunk_offsets[msc->next_chunk] < offset)) {
1382
	    sc = msc;
1383
	    offset = msc->chunk_offsets[msc->next_chunk];
1384
	    //printf("SELETED  %Ld  i:%d\n", offset, i);
1240 1385
        }
1241 1386
    }
1242
    mov->streams[st_id]->next_chunk++;
1243
    if(offset==0x0FFFFFFFFFFFFFFF)
1244
        return -1;
1245
    
1387
    if (!sc || offset==0x0FFFFFFFFFFFFFFF)
1388
	return -1;
1389

  
1390
    sc->next_chunk++;
1391

  
1246 1392
    if(mov->next_chunk_offset < offset) { /* some meta data */
1247 1393
        url_fskip(&s->pb, (offset - mov->next_chunk_offset));
1248 1394
        mov->next_chunk_offset = offset;
1249 1395
    }
1250 1396

  
1251 1397
//printf("chunk: [%i] %lli -> %lli\n", st_id, mov->next_chunk_offset, offset);
1252
    if(!mov->streams[st_id]->is_ff_stream) {
1398
    if(!sc->is_ff_stream) {
1253 1399
        url_fskip(&s->pb, (offset - mov->next_chunk_offset));
1254 1400
        mov->next_chunk_offset = offset;
1255 1401
        offset = 0x0FFFFFFFFFFFFFFF;
......
1259 1405
    /* now get the chunk size... */
1260 1406

  
1261 1407
    for(i=0; i<mov->total_streams; i++) {
1262
        if((mov->streams[i]->next_chunk < mov->streams[i]->chunk_count)
1263
        && ((mov->streams[i]->chunk_offsets[mov->streams[i]->next_chunk] - offset) < size)) {
1264
            size = mov->streams[i]->chunk_offsets[mov->streams[i]->next_chunk] - offset;
1265
        }
1408
	MOVStreamContext *msc = mov->streams[i];
1409
	if ((msc->next_chunk < msc->chunk_count)
1410
	    && ((msc->chunk_offsets[msc->next_chunk] - offset) < size))
1411
	    size = msc->chunk_offsets[msc->next_chunk] - offset;
1266 1412
    }
1267 1413
#ifdef MOV_SPLIT_CHUNKS
1268 1414
    /* split chunks into samples */
1269
    if(mov->streams[st_id]->sample_size == 0) {
1270
        int idx;
1271
        idx = mov->streams[st_id]->sample_to_chunk_index;
1272
        if ((idx + 1 < mov->streams[st_id]->sample_to_chunk_sz)
1273
               && (mov->streams[st_id]->next_chunk >= mov->streams[st_id]->sample_to_chunk[idx + 1].first))
1274
           idx++; 
1275
        mov->streams[st_id]->sample_to_chunk_index = idx;
1276
        if(idx >= 0 && mov->streams[st_id]->sample_to_chunk[idx].count != 1) {
1277
            mov->partial = st_id+1;
1415
    if (sc->sample_size == 0) {
1416
        int idx = sc->sample_to_chunk_index;
1417
        if ((idx + 1 < sc->sample_to_chunk_sz)
1418
	    && (sc->next_chunk >= sc->sample_to_chunk[idx + 1].first))
1419
           idx++;
1420
        sc->sample_to_chunk_index = idx;
1421
        if (idx >= 0 && sc->sample_to_chunk[idx].count != 1) {
1422
	    mov->partial = sc;
1278 1423
            /* we'll have to get those samples before next chunk */
1279
            mov->streams[st_id]->left_in_chunk = (mov->streams[st_id]->sample_to_chunk[idx].count) - 1;
1280
            size = mov->streams[st_id]->sample_sizes[mov->streams[st_id]->current_sample];
1424
            sc->left_in_chunk = sc->sample_to_chunk[idx].count - 1;
1425
            size = sc->sample_sizes[sc->current_sample];
1281 1426
        }
1282 1427

  
1283
        mov->streams[st_id]->current_sample++;
1428
        sc->current_sample++;
1284 1429
    }
1285 1430
#endif
1286 1431

  
......
1293 1438
    if(size == 0)
1294 1439
        return -1;
1295 1440
    url_fseek(&s->pb, offset, SEEK_SET);
1296
    sc = mov->streams[st_id];
1441

  
1442
    //printf("READCHUNK hlen: %d  %d off: %Ld   pos:%Ld\n", size, sc->header_len, offset, url_ftell(&s->pb));
1297 1443
    if (sc->header_len > 0) {
1298 1444
        av_new_packet(pkt, size + sc->header_len);
1299 1445
        memcpy(pkt->data, sc->header_data, sc->header_len);

Also available in: Unified diff