if (sc->sample_size == 0) { idx = sc->sample_to_chunk_index; if ((idx + 1 < sc->sample_to_chunk_sz) && (sc->next_chunk >= sc->sample_to_chunk[idx + 1].first)) idx++; sc->sample_to_chunk_index = idx;
if (sc->sample_size == 0 || sc->sample_size > 100) {
static int mov_read_packet(AVFormatContext *s, AVPacket *pkt){    MOVContext *mov = (MOVContext *) s->priv_data;    MOVStreamContext *sc;    int64_t offset = INT64_MAX;    int64_t best_dts = INT64_MAX;    int i, a, b, m;    int size;    int idx;    size = 0x0FFFFFFF;#ifdef MOV_SPLIT_CHUNKS    if (mov->partial) {	sc = mov->partial;	idx = sc->sample_to_chunk_index;        if (idx < 0) return 0;#ifdef DEBUG        fprintf(stderr, "sc[ffid %d]->sample_size = %d\n", sc->ffindex, sc->sample_size);#endif        //size = sc->sample_sizes[sc->current_sample];        // that ain't working...        //size = (sc->sample_size)?sc->sample_size:sc->sample_sizes[sc->current_sample];        size = (sc->sample_size > 1)?sc->sample_size:sc->sample_sizes[sc->current_sample];        sc->current_sample++;        sc->left_in_chunk--;        if (sc->left_in_chunk <= 0)            mov->partial = 0;        offset = mov->next_chunk_offset;        /* extract the sample */        goto readchunk;    }#endifagain:    sc = 0;    if(offset == INT64_MAX)        best_dts= INT64_MAX;    for(i=0; i<mov->total_streams; i++) {	MOVStreamContext *msc = mov->streams[i];        if ((msc->next_chunk < msc->chunk_count) && msc->next_chunk >= 0){            if (msc->sample_to_time_index < msc->stts_count && mov->ni) {                int64_t dts;                int index= msc->sample_to_time_index;                int sample= msc->sample_to_time_sample;                int time= msc->sample_to_time_time;                int duration = msc->stts_data[index].duration;                int count = msc->stts_data[index].count;                if (sample + count < msc->current_sample) {                    sample += count;                    time   += count*duration;                    index ++;                    duration = msc->stts_data[index].duration;                }                dts = time + (msc->current_sample-1 - sample) * (int64_t)duration;                dts = av_rescale(dts, AV_TIME_BASE, msc->time_scale);//                av_log(NULL, AV_LOG_DEBUG, "%d %Ld %Ld %Ld \n", i, dts, best_dts, offset);                if(dts < best_dts){                    best_dts= dts;                    sc = msc;                    offset = msc->chunk_offsets[msc->next_chunk];                }            }else{            //av_log(NULL, AV_LOG_DEBUG, "MOCHUNK %ld  %d   %p  pos:%Ld\n", mov->streams[i]->next_chunk, mov->total_streams, mov->streams[i], url_ftell(&s->pb));                if ((msc->chunk_offsets[msc->next_chunk] < offset)) {                    sc = msc;                    offset = msc->chunk_offsets[msc->next_chunk];                    //av_log(NULL, AV_LOG_DEBUG, "SELETED  %Ld  i:%d\n", offset, i);                }            }        }    }    if (!sc || offset==INT64_MAX)	return -1;    sc->next_chunk++;    if(mov->next_chunk_offset < offset) { /* some meta data */        url_fskip(&s->pb, (offset - mov->next_chunk_offset));        mov->next_chunk_offset = offset;    }//av_log(NULL, AV_LOG_DEBUG, "chunk: [%i] %lli -> %lli\n", st_id, mov->next_chunk_offset, offset);    if(!sc->is_ff_stream || (s->streams[sc->ffindex]->discard >= AVDISCARD_ALL)) {        url_fskip(&s->pb, (offset - mov->next_chunk_offset));        mov->next_chunk_offset = offset;	offset = INT64_MAX;        goto again;    }    /* now get the chunk size... */    for(i=0; i<mov->total_streams; i++) {	MOVStreamContext *msc = mov->streams[i];	if ((msc->next_chunk < msc->chunk_count)            && msc->chunk_offsets[msc->next_chunk] - offset < size            && msc->chunk_offsets[msc->next_chunk] > offset)	    size = msc->chunk_offsets[msc->next_chunk] - offset;    }#ifdef MOV_MINOLTA_FIX    //Make sure that size is according to sample_size (Needed by .mov files     //created on a Minolta Dimage Xi where audio chunks contains waste data in the end)    //Maybe we should really not only check sc->sample_size, but also sc->sample_sizes    //but I have no such movies    if (sc->sample_size > 0) {         int foundsize=0;        for(i=0; i<(sc->sample_to_chunk_sz); i++) {            if( (sc->sample_to_chunk[i].first)<=(sc->next_chunk) )            {		// I can't figure out why for PCM audio sample_size is always 1		// (it should actually be channels*bits_per_second/8) but it is.		AVCodecContext* cod = &s->streams[sc->ffindex]->codec;                if (sc->sample_size == 1 && (cod->codec_id == CODEC_ID_PCM_S16BE || cod->codec_id == CODEC_ID_PCM_S16LE))		    foundsize=(sc->sample_to_chunk[i].count*cod->channels*cod->bits_per_sample)/8;		else		    foundsize=sc->sample_to_chunk[i].count*sc->sample_size;            }#ifdef DEBUG            av_log(NULL, AV_LOG_DEBUG, "sample_to_chunk first=%ld count=%ld, id=%ld\n", sc->sample_to_chunk[i].first, sc->sample_to_chunk[i].count, sc->sample_to_chunk[i].id);#endif        }        if( (foundsize>0) && (foundsize<size) )        {#ifdef DEBUG            /*av_log(NULL, AV_LOG_DEBUG, "this size should actually be %d\n",foundsize);*/#endif            size=foundsize;        }    }#endif //MOV_MINOLTA_FIX#ifdef MOV_SPLIT_CHUNKS    /* split chunks into samples */    if (sc->sample_size == 0) {        idx = sc->sample_to_chunk_index;        if ((idx + 1 < sc->sample_to_chunk_sz)                && (sc->next_chunk >= sc->sample_to_chunk[idx + 1].first))            idx++;        sc->sample_to_chunk_index = idx;        if (idx >= 0 && sc->sample_to_chunk[idx].count != 1) {	    mov->partial = sc;            /* we'll have to get those samples before next chunk */            sc->left_in_chunk = sc->sample_to_chunk[idx].count - 1;            size = (sc->sample_size > 1)?sc->sample_size:sc->sample_sizes[sc->current_sample];        }        sc->current_sample++;    }#endifreadchunk:#ifdef DEBUG    av_log(NULL, AV_LOG_DEBUG, "chunk: %lli -> %lli (%i)\n", offset, offset + size, size);#endif    if(size == 0x0FFFFFFF)        size = mov->mdat_size + mov->mdat_offset - offset;    if(size < 0)        return -1;    if(size == 0)        return -1;    url_fseek(&s->pb, offset, SEEK_SET);    //av_log(NULL, AV_LOG_DEBUG, "READCHUNK hlen: %d  %d off: %Ld   pos:%Ld\n", size, sc->header_len, offset, url_ftell(&s->pb));    if (sc->header_len > 0) {        av_new_packet(pkt, size + sc->header_len);        memcpy(pkt->data, sc->header_data, sc->header_len);        get_buffer(&s->pb, pkt->data + sc->header_len, size);        /* free header */        av_freep(&sc->header_data);        sc->header_len = 0;    } else {        av_new_packet(pkt, size);        get_buffer(&s->pb, pkt->data, pkt->size);    }    pkt->stream_index = sc->ffindex;        // If the keyframes table exists, mark any samples that are in the table as key frames.    // If no table exists, treat very sample as a key frame.    if (sc->keyframes) {                a = 0;        b = sc->keyframe_count - 1;                while (a < b) {            m = (a + b + 1) >> 1;            if (sc->keyframes[m] > sc->current_sample) {                b = m - 1;            } else {                a = m;            }            }                if (sc->keyframes[a] == sc->current_sample)            pkt->flags |= PKT_FLAG_KEY;    }    else        pkt->flags |= PKT_FLAG_KEY;#ifdef DEBUG/*    av_log(NULL, AV_LOG_DEBUG, "Packet (%d, %ld) ", pkt->stream_index, pkt->size);    for(i=0; i<8; i++)        av_log(NULL, AV_LOG_DEBUG, "%02x ", pkt->data[i]);    for(i=0; i<8; i++)        av_log(NULL, AV_LOG_DEBUG, "%c ", (pkt->data[i]) & 0x7F);    av_log(NULL, AV_LOG_DEBUG, "\n");*/#endif    mov->next_chunk_offset = offset + size;        /* find the corresponding dts */	     if (sc && sc->sample_to_time_index < sc->stts_count && pkt) {	       unsigned int count;      uint64_t dts, pts;      unsigned int duration = sc->stts_data[sc->sample_to_time_index].duration;      count = sc->stts_data[sc->sample_to_time_index].count;      if ((sc->sample_to_time_sample + count) < sc->current_sample) {	         sc->sample_to_time_sample += count;	         sc->sample_to_time_time   += count*duration;	         sc->sample_to_time_index ++;	         duration = sc->stts_data[sc->sample_to_time_index].duration;      }	       dts = sc->sample_to_time_time + (sc->current_sample-1 - sc->sample_to_time_sample) * (int64_t)duration;        /* find the corresponding pts */        if (sc->sample_to_ctime_index < sc->ctts_count) {            int duration = sc->ctts_data[sc->sample_to_ctime_index].duration;            int count = sc->ctts_data[sc->sample_to_ctime_index].count;            if ((sc->sample_to_ctime_sample + count) < sc->current_sample) {                sc->sample_to_ctime_sample += count;                sc->sample_to_ctime_index ++;                duration = sc->ctts_data[sc->sample_to_ctime_index].duration;            }            pts = dts + duration;        }else            pts = dts;        pkt->pts = av_rescale( pts,                         (int64_t)s->streams[sc->ffindex]->time_base.den,                         (int64_t)sc->time_scale * (int64_t)s->streams[sc->ffindex]->time_base.num );        pkt->dts = av_rescale( dts,                         (int64_t)s->streams[sc->ffindex]->time_base.den,                         (int64_t)sc->time_scale * (int64_t)s->streams[sc->ffindex]->time_base.num );#ifdef DEBUG    av_log(NULL, AV_LOG_DEBUG, "stream #%d smp #%ld dts = %lld pts = %lld (smp:%ld time:%lld idx:%d ent:%d count:%d dur:%d)\n"      , pkt->stream_index, sc->current_sample-1, pkt->dts, pkt->pts      , sc->sample_to_time_sample      , sc->sample_to_time_time      , sc->sample_to_time_index      , sc->stts_count      , count      , duration);#endif    }    return 0;}