Beispiel #1
0
/**
 * Store calculated hash into the given array.
 *
 * @param ctx the algorithm context containing current hashing state
 * @param result calculated hash in binary form
 */
void rhash_tiger_final(tiger_ctx *ctx, unsigned char result[24])
{
	unsigned index = (unsigned)ctx->length & 63;
	uint64_t* msg64 = (uint64_t*)ctx->message;

	/* pad message and run for last block */

	/* append the byte 0x01 to the message */
	ctx->message[index++] = (ctx->tiger2 ? 0x80 : 0x01);

	/* if no room left in the message to store 64-bit message length */
	if(index > 56) {
		/* then fill the rest with zeros and process it */
		while(index < 64) {
			ctx->message[index++] = 0;
		}
		rhash_tiger_process_block(ctx->hash, msg64);
		index = 0;
	}
	while(index < 56) {
		ctx->message[index++] = 0;
	}
	msg64[7] = le2me_64(ctx->length << 3);
	rhash_tiger_process_block(ctx->hash, msg64);

	/* save result hash */
	le64_copy(result, 0, &ctx->hash, 24);
}
Beispiel #2
0
void tiger_final(tiger_ctx *ctx, unsigned char result[24]) {
    unsigned index = (unsigned)ctx->length & 63;

    /* pad message and run for last block */
    ctx->message[index++] = 0x01;
    while( index&7 ) {
        ctx->message[index++] = 0;
    }

    /* if no room left in the message to store 64-bit message length */
    if(index>56) {
        /* then pad the rest with zeros and process it */
        while(index < 64) {
            ctx->message[index++] = 0;
        }
        tiger_process_message_block(ctx->state, (uint64_t*)ctx->message);
        index = 0;
    }
    while(index < 56) {
        ctx->message[index++] = 0;
    }
    ((uint64_t*)(&(ctx->message[56])))[0] = le2me_64(ctx->length << 3);
    tiger_process_message_block(ctx->state, (uint64_t*)ctx->message);

    /* save result hash */
    memcpy(result, &ctx->state, 24);
}
Beispiel #3
0
static int seek(stream_t *s,off_t newpos) {
  uint64_t pos = le2me_64((uint64_t)newpos);
  mp_net_stream_packet_t* pack;

  pack = send_net_stream_cmd(s,NET_STREAM_SEEK,(char*)&pos,8);
  if(!pack) {
    return 0;
  }
  s->pos = newpos;
  free(pack);
  return 1;
}
Beispiel #4
0
void av_md5_final(AVMD5 *ctx, uint8_t *dst){
    int i;
    uint64_t finalcount= le2me_64(ctx->len<<3);

    av_md5_update(ctx, "\200", 1);
    while((ctx->len & 63)<56)
        av_md5_update(ctx, "", 1);

    av_md5_update(ctx, &finalcount, 8);

    for(i=0; i<4; i++)
        ((uint32_t*)dst)[i]= le2me_32(ctx->ABCD[3-i]);
}
Beispiel #5
0
/*
 * get file property.
 * return value        packet size  ... success
 *                              -1  ... error
 */
int asf_get_file_property(const uint8_t *header,int asf_header_size,
			  struct asf_file_header_t *fileh)
{
    int pos = 0;
    int packet_size = 0;
  
    /*
      examine file properties
    */
    pos = find_asf_guid(header,0,asf_file_header_guid,asf_header_size);
    
    if(pos < 0) {
	goto failed;
    }
    
    if((pos + sizeof(struct asf_file_header_t )) > asf_header_size) {/* 2big */
	goto failed;
    }
    
    memcpy((uint8_t *)fileh,header + pos,sizeof(struct asf_file_header_t));
    
    /* little endian */
    fileh->file_size       = le2me_64(fileh->file_size);
    fileh->creation_time   = le2me_64(fileh->creation_time);
    fileh->num_packets     = le2me_64(fileh->num_packets);
    fileh->play_duration   = le2me_64(fileh->play_duration);
    fileh->send_duration   = le2me_64(fileh->send_duration);
    fileh->preroll         = le2me_64(fileh->preroll);
    fileh->flags           = le2me_32(fileh->flags);
    fileh->min_packet_size = le2me_32(fileh->min_packet_size);
    fileh->max_packet_size = le2me_32(fileh->max_packet_size);
    fileh->max_bitrate     = le2me_32(fileh->max_bitrate);
    
    display(MSDL_VER,"file size = %lld\n",fileh->file_size);
    display(MSDL_VER,"play_duration = %d\n",
	    fileh->play_duration/10000000);
    display(MSDL_VER,"send_duration = %d\n",
	    fileh->send_duration/10000000);
    display(MSDL_VER,"# of packets = %d\n",
	    fileh->num_packets);
    display(MSDL_VER,"flags = %x\n",
	    fileh->flags);
	
    packet_size = fileh->max_packet_size;

    display(MSDL_VER,"packet_size = %d\n",
	    fileh->max_packet_size);
    display(MSDL_VER,"min_packsize = %d\n",
	    fileh->min_packet_size);
    
    return packet_size;
    
  failed:
    return -1;
}
Beispiel #6
0
/**
 * The core transformation. Process a 512-bit block.
 *
 * @param state the algorithm state
 * @param block the message block to process
 */
static void rhash_tiger_process_block(uint64_t state[3], uint64_t* block)
{
	/* Optimized for GCC IA32.
	   The order of declarations is important for compiler. */
	uint64_t a, b, c;
	uint64_t x0, x1, x2, x3, x4, x5, x6, x7;
#ifndef CPU_X64
	uint64_t tmp;
	char i;
#endif

	x0 = le2me_64(block[0]); x1 = le2me_64(block[1]);
	x2 = le2me_64(block[2]); x3 = le2me_64(block[3]);
	x4 = le2me_64(block[4]); x5 = le2me_64(block[5]);
	x6 = le2me_64(block[6]); x7 = le2me_64(block[7]);

	a = state[0];
	b = state[1];
	c = state[2];

	/* passes and key shedules */
#ifndef CPU_X64
	for(i = 0; i < 3; i++) {
		if(i != 0) key_schedule;
		pass(a, b, c, (i == 0 ? 5 : i == 1 ? 7 : 9));
		tmp = a;
		a = c;
		c = b;
		b = tmp;
	}
#else
	pass(a, b, c, 5);
	key_schedule;
	pass(c, a, b, 7);
	key_schedule;
	pass(b, c, a, 9);
#endif

	/* feedforward operation */
	state[0] = a ^ state[0];
	state[1] = b - state[1];
	state[2] = c + state[2];
}
int handle_client(client_t* cl,mp_net_stream_packet_t* pack) {

  if(!pack)
    return 0;
 
  switch(pack->cmd) {
  case NET_STREAM_OPEN:
    if(((char*)pack)[pack->len-1] != '\0') {
      mp_msg(MSGT_NETST,MSGL_WARN,"Got invalid open packet\n");
      return 0;
    }
    return net_stream_open(cl,pack->data);
  case NET_STREAM_FILL_BUFFER:
    if(pack->len != sizeof(mp_net_stream_packet_t) + 2) {
      mp_msg(MSGT_NETST,MSGL_WARN,"Got invalid fill buffer packet\n");
      return 0;
    }
    return net_stream_fill_buffer(cl,le2me_16(*((uint16_t*)pack->data)));
  case NET_STREAM_SEEK:
    if(pack->len != sizeof(mp_net_stream_packet_t) + 8) {
      mp_msg(MSGT_NETST,MSGL_WARN,"Got invalid fill buffer packet\n");
      return 0;
    }
    return net_stream_seek(cl,le2me_64(*((uint64_t*)pack->data)));
  case NET_STREAM_RESET:
    return net_stream_reset(cl);
  case NET_STREAM_CLOSE:
    if(pack->len != sizeof(mp_net_stream_packet_t)){
      mp_msg(MSGT_NETST,MSGL_WARN,"Got invalid fill buffer packet\n");
      return 0;
    }
    return net_stream_close(cl);
  default:
    mp_msg(MSGT_NETST,MSGL_WARN,"Got unknown command %d\n",pack->cmd);
    if(!write_error(cl->fd,"Unknown command\n"))
      return 0;
  }
  return 0;
}
Beispiel #8
0
/* process a 512-bit block */
static void tiger_process_message_block(uint64_t state[3], uint64_t* block) {
    /* Optimized for GCC IA32.
       The order of declarations is important for compiler. */
    register uint64_t a, b, c;
    register uint64_t x0, x1, x2, x3, x4, x5, x6, x7;
    register uint64_t tmp;
    char i;

    x0=le2me_64(block[0]);
    x1=le2me_64(block[1]);
    x2=le2me_64(block[2]);
    x3=le2me_64(block[3]);
    x4=le2me_64(block[4]);
    x5=le2me_64(block[5]);
    x6=le2me_64(block[6]);
    x7=le2me_64(block[7]);

    a = state[0];
    b = state[1];
    c = state[2];

    /* passes and key shedules */
    for(i=0; i<3; i++) {
        if(i != 0) key_schedule;
        pass(a, b, c, ( i==0 ? 5 : i==1 ? 7 : 9 ));
        tmp=a;
        a=c;
        c=b;
        b=tmp;
    }

    /* feedforward operation */
    state[0] = a ^ state[0];
    state[1] = b - state[1];
    state[2] = c + state[2];
}
Beispiel #9
0
/**
 * The core transformation. Process the specified block of data.
 *
 * @param hash the algorithm state
 * @param block the message block to process
 * @param block_size the size of the processed block in bytes
 */
static void Sha3ProcessBlock(uint64_t hash[25], const uint64_t *block, size_t block_size)
{
	hash[ 0] ^= le2me_64(block[ 0]);
	hash[ 1] ^= le2me_64(block[ 1]);
	hash[ 2] ^= le2me_64(block[ 2]);
	hash[ 3] ^= le2me_64(block[ 3]);
	hash[ 4] ^= le2me_64(block[ 4]);
	hash[ 5] ^= le2me_64(block[ 5]);
	hash[ 6] ^= le2me_64(block[ 6]);
	hash[ 7] ^= le2me_64(block[ 7]);
	hash[ 8] ^= le2me_64(block[ 8]);
	hash[ 9] ^= le2me_64(block[ 9]);
	hash[10] ^= le2me_64(block[10]);
	hash[11] ^= le2me_64(block[11]);
	hash[12] ^= le2me_64(block[12]);
	hash[13] ^= le2me_64(block[13]);
	hash[14] ^= le2me_64(block[14]);
	hash[15] ^= le2me_64(block[15]);
	hash[16] ^= le2me_64(block[16]);
	hash[17] ^= le2me_64(block[17]);
		#ifdef FULL_SHA3_FAMILY_SUPPORT
			hash[18] ^= le2me_64(block[18]);
			hash[19] ^= le2me_64(block[19]);
			hash[20] ^= le2me_64(block[20]);
			hash[21] ^= le2me_64(block[21]);
			hash[22] ^= le2me_64(block[22]);
			hash[23] ^= le2me_64(block[23]);
			hash[24] ^= le2me_64(block[24]);
		#endif
	/* make a permutation of the hash */
	Sha3Permutation(hash);
}
Beispiel #10
0
int read_asf_header(demuxer_t *demuxer,struct asf_priv* asf) {
    int hdr_len = asf->header.objh.size - sizeof(asf->header);
    int hdr_skip = 0;
    char *hdr = NULL;
    char guid_buffer[16];
    int pos, start = stream_tell(demuxer->stream);
    uint32_t* streams = NULL;
    int audio_streams=0;
    int video_streams=0;
    uint16_t stream_count=0;
    int best_video = -1;
    int best_audio = -1;
    uint64_t data_len;
    ASF_stream_header_t *streamh;
    uint8_t *buffer;
    int audio_pos=0;

    if(hdr_len < 0) {
        mp_msg(MSGT_HEADER, MSGL_FATAL, "Header size is too small.\n");
        return 0;
    }

    if (hdr_len > 1024 * 1024) {
        mp_tmsg(MSGT_HEADER, MSGL_ERR, "FATAL: header size bigger than 1 MB (%d)!\nPlease contact MPlayer authors, and upload/send this file.\n",
                hdr_len);
        hdr_skip = hdr_len - 1024 * 1024;
        hdr_len = 1024 * 1024;
    }
    hdr = malloc(hdr_len);
    if (!hdr) {
        mp_tmsg(MSGT_HEADER, MSGL_FATAL, "Could not allocate %d bytes for header.\n",
                hdr_len);
        return 0;
    }
    stream_read(demuxer->stream, hdr, hdr_len);
    if (hdr_skip)
        stream_skip(demuxer->stream, hdr_skip);
    if (stream_eof(demuxer->stream)) {
        mp_tmsg(MSGT_HEADER, MSGL_FATAL, "EOF while reading ASF header, broken/incomplete file?\n");
        goto err_out;
    }

    if (is_drm(hdr, hdr_len))
        mp_tmsg(MSGT_HEADER, MSGL_FATAL, "This file has been encumbered with DRM encryption, it will not play in MPlayer!\n");

    if ((pos = find_asf_guid(hdr, asf_ext_stream_audio, 0, hdr_len)) >= 0)
    {
        // Special case: found GUID for dvr-ms audio.
        // Now skip back to associated stream header.
        int sh_pos=0;

        sh_pos = find_backwards_asf_guid(hdr, asf_stream_header_guid, pos);

        if (sh_pos > 0) {
            sh_audio_t *sh_audio;

            mp_msg(MSGT_HEADER, MSGL_V, "read_asf_header found dvr-ms audio stream header pos=%d\n", sh_pos);
            // found audio stream header - following code reads header and
            // initializes audio stream.
            audio_pos = pos - 16 - 8;
            streamh = (ASF_stream_header_t *)&hdr[sh_pos];
            le2me_ASF_stream_header_t(streamh);
            audio_pos += 64; //16+16+4+4+4+16+4;
            buffer = &hdr[audio_pos];
            sh_audio=new_sh_audio(demuxer,streamh->stream_no & 0x7F);
            sh_audio->needs_parsing = 1;
            mp_tmsg(MSGT_DEMUX, MSGL_INFO, "[%s] Audio stream found, -aid %d\n", "asfheader", streamh->stream_no & 0x7F);
            ++audio_streams;
            if (!asf_init_audio_stream(demuxer, asf, sh_audio, streamh, &audio_pos, &buffer, hdr, hdr_len))
                goto len_err_out;
            if (!get_ext_stream_properties(hdr, hdr_len, streamh->stream_no, asf, 0))
                goto len_err_out;
        }
    }
    // find stream headers
    // only reset pos if we didnt find dvr_ms audio stream
    // if we did find it then we want to avoid reading its header twice
    if (audio_pos == 0)
        pos = 0;

    while ((pos = find_asf_guid(hdr, asf_stream_header_guid, pos, hdr_len)) >= 0)
    {
        streamh = (ASF_stream_header_t *)&hdr[pos];
        pos += sizeof(ASF_stream_header_t);
        if (pos > hdr_len) goto len_err_out;
        le2me_ASF_stream_header_t(streamh);
        mp_msg(MSGT_HEADER, MSGL_V, "stream type: %s\n",
               asf_chunk_type(streamh->type));
        mp_msg(MSGT_HEADER, MSGL_V, "stream concealment: %s\n",
               asf_chunk_type(streamh->concealment));
        mp_msg(MSGT_HEADER, MSGL_V, "type: %d bytes,  stream: %d bytes  ID: %d\n",
               (int)streamh->type_size, (int)streamh->stream_size,
               (int)streamh->stream_no);
        mp_msg(MSGT_HEADER, MSGL_V, "unk1: %lX  unk2: %X\n",
               (unsigned long)streamh->unk1, (unsigned int)streamh->unk2);
        mp_msg(MSGT_HEADER, MSGL_V, "FILEPOS=0x%X\n", pos + start);
        // type-specific data:
        buffer = &hdr[pos];
        pos += streamh->type_size;
        if (pos > hdr_len) goto len_err_out;
        switch(ASF_LOAD_GUID_PREFIX(streamh->type)) {
        case ASF_GUID_PREFIX_audio_stream: {
            sh_audio_t* sh_audio=new_sh_audio(demuxer,streamh->stream_no & 0x7F);
            mp_tmsg(MSGT_DEMUX, MSGL_INFO, "[%s] Audio stream found, -aid %d\n", "asfheader", streamh->stream_no & 0x7F);
            ++audio_streams;
            if (!asf_init_audio_stream(demuxer, asf, sh_audio, streamh, &pos, &buffer, hdr, hdr_len))
                goto len_err_out;
            //if(demuxer->audio->id==-1) demuxer->audio->id=streamh.stream_no & 0x7F;
            break;
        }
        case ASF_GUID_PREFIX_video_stream: {
            unsigned int len;
            float asp_ratio;
            sh_video_t* sh_video=new_sh_video(demuxer,streamh->stream_no & 0x7F);
            mp_tmsg(MSGT_DEMUX, MSGL_INFO, "[%s] Video stream found, -vid %d\n", "asfheader", streamh->stream_no & 0x7F);
            len=streamh->type_size-(4+4+1+2);
            ++video_streams;
//        sh_video->bih=malloc(chunksize); memset(sh_video->bih,0,chunksize);
            sh_video->bih=calloc((len<sizeof(BITMAPINFOHEADER))?sizeof(BITMAPINFOHEADER):len,1);
            memcpy(sh_video->bih,&buffer[4+4+1+2],len);
            le2me_BITMAPINFOHEADER(sh_video->bih);
            if (sh_video->bih->biSize > len && sh_video->bih->biSize > sizeof(BITMAPINFOHEADER))
                sh_video->bih->biSize = len;
            if (sh_video->bih->biCompression == mmioFOURCC('D', 'V', 'R', ' ')) {
                //mp_tmsg(MSGT_DEMUXER, MSGL_WARN, "DVR will probably only work with libavformat, try -demuxer 35 if you have problems\n");
                //sh_video->fps=(float)sh_video->video.dwRate/(float)sh_video->video.dwScale;
                //sh_video->frametime=(float)sh_video->video.dwScale/(float)sh_video->video.dwRate;
                asf->asf_frame_state=-1;
                asf->asf_frame_start_found=0;
                asf->asf_is_dvr_ms=1;
                asf->dvr_last_vid_pts=0.0;
            } else asf->asf_is_dvr_ms=0;
            if (!get_ext_stream_properties(hdr, hdr_len, streamh->stream_no, asf, 1))
                goto len_err_out;
            if (get_meta(hdr, hdr_len, streamh->stream_no, &asp_ratio)) {
                sh_video->aspect = asp_ratio * sh_video->bih->biWidth /
                                   sh_video->bih->biHeight;
            }
            sh_video->i_bps = asf->bps;

            if( mp_msg_test(MSGT_DEMUX,MSGL_V) ) print_video_header(sh_video->bih, MSGL_V);
            //asf_video_id=streamh.stream_no & 0x7F;
            //if(demuxer->video->id==-1) demuxer->video->id=streamh.stream_no & 0x7F;
            break;
        }
        }
        // stream-specific data:
        // stream_read(demuxer->stream,(char*) buffer,streamh.stream_size);
    }

    // find file header
    pos = find_asf_guid(hdr, asf_file_header_guid, 0, hdr_len);
    if (pos >= 0) {
        ASF_file_header_t *fileh = (ASF_file_header_t *)&hdr[pos];
        pos += sizeof(ASF_file_header_t);
        if (pos > hdr_len) goto len_err_out;
        le2me_ASF_file_header_t(fileh);
        mp_msg(MSGT_HEADER, MSGL_V, "ASF: packets: %d  flags: %d  "
               "max_packet_size: %d  min_packet_size: %d  max_bitrate: %d  "
               "preroll: %d\n",
               (int)fileh->num_packets, (int)fileh->flags,
               (int)fileh->min_packet_size, (int)fileh->max_packet_size,
               (int)fileh->max_bitrate, (int)fileh->preroll);
        asf->packetsize=fileh->max_packet_size;
        asf->packet=malloc(asf->packetsize); // !!!
        asf->packetrate=fileh->max_bitrate/8.0/(double)asf->packetsize;
        asf->movielength=(fileh->play_duration-10000*fileh->preroll)/10000000.0;
    }

    // find content header
    pos = find_asf_guid(hdr, asf_content_desc_guid, 0, hdr_len);
    if (pos >= 0) {
        ASF_content_description_t *contenth = (ASF_content_description_t *)&hdr[pos];
        char *string=NULL;
        uint16_t* wstring = NULL;
        uint16_t len;
        pos += sizeof(ASF_content_description_t);
        if (pos > hdr_len) goto len_err_out;
        le2me_ASF_content_description_t(contenth);
        mp_msg(MSGT_HEADER,MSGL_V,"\n");
        // extract the title
        if((len = contenth->title_size) != 0) {
            wstring = (uint16_t*)&hdr[pos];
            pos += len;
            if (pos > hdr_len) goto len_err_out;
            if ((string = get_ucs2str(wstring, len))) {
                mp_msg(MSGT_HEADER,MSGL_V," Title: %s\n", string);
                demux_info_add(demuxer, "title", string);
                free(string);
            }
        }
        // extract the author
        if((len = contenth->author_size) != 0) {
            wstring = (uint16_t*)&hdr[pos];
            pos += len;
            if (pos > hdr_len) goto len_err_out;
            if ((string = get_ucs2str(wstring, len))) {
                mp_msg(MSGT_HEADER,MSGL_V," Author: %s\n", string);
                demux_info_add(demuxer, "author", string);
                free(string);
            }
        }
        // extract the copyright
        if((len = contenth->copyright_size) != 0) {
            wstring = (uint16_t*)&hdr[pos];
            pos += len;
            if (pos > hdr_len) goto len_err_out;
            if ((string = get_ucs2str(wstring, len))) {
                mp_msg(MSGT_HEADER,MSGL_V," Copyright: %s\n", string);
                demux_info_add(demuxer, "copyright", string);
                free(string);
            }
        }
        // extract the comment
        if((len = contenth->comment_size) != 0) {
            wstring = (uint16_t*)&hdr[pos];
            pos += len;
            if (pos > hdr_len) goto len_err_out;
            if ((string = get_ucs2str(wstring, len))) {
                mp_msg(MSGT_HEADER,MSGL_V," Comment: %s\n", string);
                demux_info_add(demuxer, "comments", string);
                free(string);
            }
        }
        // extract the rating
        if((len = contenth->rating_size) != 0) {
            wstring = (uint16_t*)&hdr[pos];
            pos += len;
            if (pos > hdr_len) goto len_err_out;
            if ((string = get_ucs2str(wstring, len))) {
                mp_msg(MSGT_HEADER,MSGL_V," Rating: %s\n", string);
                free(string);
            }
        }
        mp_msg(MSGT_HEADER,MSGL_V,"\n");
    }

    // find content header
    pos = find_asf_guid(hdr, asf_stream_group_guid, 0, hdr_len);
    if (pos >= 0) {
        int max_streams = (hdr_len - pos - 2) / 6;
        uint16_t stream_id, i;
        uint32_t max_bitrate;
        char *ptr = &hdr[pos];
        mp_msg(MSGT_HEADER,MSGL_V,"============ ASF Stream group == START ===\n");
        if(max_streams <= 0) goto len_err_out;
        stream_count = AV_RL16(ptr);
        ptr += sizeof(uint16_t);
        if(stream_count > max_streams) stream_count = max_streams;
        if(stream_count > 0)
            streams = malloc(2*stream_count*sizeof(uint32_t));
        mp_msg(MSGT_HEADER,MSGL_V," stream count=[0x%x][%u]\n", stream_count, stream_count );
        for( i=0 ; i<stream_count ; i++ ) {
            stream_id = AV_RL16(ptr);
            ptr += sizeof(uint16_t);
            memcpy(&max_bitrate, ptr, sizeof(uint32_t));// workaround unaligment bug on sparc
            max_bitrate = le2me_32(max_bitrate);
            ptr += sizeof(uint32_t);
            mp_msg(MSGT_HEADER,MSGL_V,"   stream id=[0x%x][%u]\n", stream_id, stream_id );
            mp_msg(MSGT_HEADER,MSGL_V,"   max bitrate=[0x%x][%u]\n", max_bitrate, max_bitrate );
            streams[2*i] = stream_id;
            streams[2*i+1] = max_bitrate;
        }
        mp_msg(MSGT_HEADER,MSGL_V,"============ ASF Stream group == END ===\n");
    }
    free(hdr);
    hdr = NULL;
    start = stream_tell(demuxer->stream); // start of first data chunk
    stream_read(demuxer->stream, guid_buffer, 16);
    if (memcmp(guid_buffer, asf_data_chunk_guid, 16) != 0) {
        mp_tmsg(MSGT_HEADER, MSGL_FATAL, "No data chunk following header!\n");
        free(streams);
        streams = NULL;
        return 0;
    }
    // read length of chunk
    stream_read(demuxer->stream, (char *)&data_len, sizeof(data_len));
    data_len = le2me_64(data_len);
    demuxer->movi_start = stream_tell(demuxer->stream) + 26;
    demuxer->movi_end = start + data_len;
    mp_msg(MSGT_HEADER, MSGL_V, "Found movie at 0x%X - 0x%X\n",
           (int)demuxer->movi_start, (int)demuxer->movi_end);

    if(streams) {
        // stream selection is done in the network code, it shouldn't be done here
        // as the servers often do not care about what we requested.
#if 0
        uint32_t vr = 0, ar = 0,i;
#ifdef CONFIG_NETWORK
        if( demuxer->stream->streaming_ctrl!=NULL ) {
            if( demuxer->stream->streaming_ctrl->bandwidth!=0 && demuxer->stream->streaming_ctrl->data!=NULL ) {
                best_audio = ((asf_http_streaming_ctrl_t*)demuxer->stream->streaming_ctrl->data)->audio_id;
                best_video = ((asf_http_streaming_ctrl_t*)demuxer->stream->streaming_ctrl->data)->video_id;
            }
        } else
#endif
            for(i = 0; i < stream_count; i++) {
                uint32_t id = streams[2*i];
                uint32_t rate = streams[2*i+1];
                if(demuxer->v_streams[id] && rate > vr) {
                    vr = rate;
                    best_video = id;
                } else if(demuxer->a_streams[id] && rate > ar) {
                    ar = rate;
                    best_audio = id;
                }
            }
#endif
        free(streams);
        streams = NULL;
    }

    mp_msg(MSGT_HEADER,MSGL_V,"ASF: %d audio and %d video streams found\n",audio_streams,video_streams);
    if(!audio_streams) demuxer->audio->id=-2;  // nosound
    else if(best_audio > 0 && demuxer->audio->id == -1) demuxer->audio->id=best_audio;
    if(!video_streams) {
        if(!audio_streams) {
            mp_tmsg(MSGT_HEADER,MSGL_ERR,"ASF: no audio or video headers found - broken file?\n");
            return 0;
        }
        demuxer->video->id=-2; // audio-only
    } else if (best_video > 0 && demuxer->video->id == -1) demuxer->video->id = best_video;

#if 0
    if( mp_msg_test(MSGT_HEADER,MSGL_V) ) {
        printf("ASF duration: %d\n",(int)fileh.duration);
        printf("ASF start pts: %d\n",(int)fileh.start_timestamp);
        printf("ASF end pts: %d\n",(int)fileh.end_timestamp);
    }
#endif

    return 1;

len_err_out:
    mp_tmsg(MSGT_HEADER, MSGL_FATAL, "Invalid length in ASF header!\n");
err_out:
    if (hdr) free(hdr);
    if (streams) free(streams);
    return 0;
}