asfheader.c

来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 766 行 · 第 1/2 页

C
766
字号
  key_len = AV_RL32(buf);  CHECKDEC(buf_len, key_len + 4);  buf += 4;  buf[key_len - 1] = '\0';  mp_msg(MSGT_HEADER, MSGL_V, "DRM Key ID: %s\n", buf);   buf += key_len;  url_len = AV_RL32(buf);  CHECKDEC(buf_len, url_len);  buf += 4;  buf[url_len - 1] = '\0';  mp_msg(MSGT_HEADER, MSGL_INFO, MSGTR_MPDEMUX_ASFHDR_DRMLicenseURL, buf);  return 1;} static int asf_init_audio_stream(demuxer_t *demuxer,struct asf_priv* asf, sh_audio_t* sh_audio, ASF_stream_header_t *streamh, int *ppos, uint8_t** buf, char *hdr, unsigned int hdr_len){  uint8_t *buffer = *buf;  int pos = *ppos;  sh_audio->wf=calloc((streamh->type_size<sizeof(WAVEFORMATEX))?sizeof(WAVEFORMATEX):streamh->type_size,1);  memcpy(sh_audio->wf,buffer,streamh->type_size);  le2me_WAVEFORMATEX(sh_audio->wf);  if( mp_msg_test(MSGT_HEADER,MSGL_V) ) print_wave_header(sh_audio->wf,MSGL_V);  if(ASF_LOAD_GUID_PREFIX(streamh->concealment)==ASF_GUID_PREFIX_audio_conceal_interleave){    buffer = &hdr[pos];    pos += streamh->stream_size;    if (pos > hdr_len) return 0;    asf->scrambling_h=buffer[0];    asf->scrambling_w=(buffer[2]<<8)|buffer[1];    asf->scrambling_b=(buffer[4]<<8)|buffer[3];    if(asf->scrambling_b>0){      asf->scrambling_w/=asf->scrambling_b;    }  } else {    asf->scrambling_b=asf->scrambling_h=asf->scrambling_w=1;  }  mp_msg(MSGT_HEADER,MSGL_V,"ASF: audio scrambling: %d x %d x %d\n",asf->scrambling_h,asf->scrambling_w,asf->scrambling_b);  return 1;}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_msg(MSGT_HEADER, MSGL_ERR, MSGTR_MPDEMUX_ASFHDR_HeaderSizeOver1MB,			hdr_len);    hdr_skip = hdr_len - 1024 * 1024;    hdr_len = 1024 * 1024;  }  hdr = malloc(hdr_len);  if (!hdr) {    mp_msg(MSGT_HEADER, MSGL_FATAL, MSGTR_MPDEMUX_ASFHDR_HeaderMallocFailed,            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_msg(MSGT_HEADER, MSGL_FATAL, MSGTR_MPDEMUX_ASFHDR_EOFWhileReadingHeader);    goto err_out;  }  if (is_drm(hdr, hdr_len))    mp_msg(MSGT_HEADER, MSGL_FATAL, MSGTR_MPDEMUX_ASFHDR_DRMProtected);  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);      mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_AudioID, "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_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_AudioID, "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_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_VideoID, "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_msg(MSGT_DEMUXER, MSGL_WARN, MSGTR_MPDEMUX_ASFHDR_DVRWantsLibavformat);          //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-fileh->preroll)/10000000LL;  }  // 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, "name", 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) {        uint16_t stream_id, i;        uint32_t max_bitrate;        char *ptr = &hdr[pos];        mp_msg(MSGT_HEADER,MSGL_V,"============ ASF Stream group == START ===\n");        stream_count = AV_RL16(ptr);        ptr += sizeof(uint16_t);        if (ptr > &hdr[hdr_len]) goto len_err_out;        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);          if (ptr > &hdr[hdr_len]) goto len_err_out;          memcpy(&max_bitrate, ptr, sizeof(uint32_t));// workaround unaligment bug on sparc          max_bitrate = le2me_32(max_bitrate);          ptr += sizeof(uint32_t);          if (ptr > &hdr[hdr_len]) goto len_err_out;          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_msg(MSGT_HEADER, MSGL_FATAL, MSGTR_MPDEMUX_ASFHDR_NoDataChunkAfterHeader);    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 MPLAYER_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;  // nosoundelse if(best_audio > 0 && demuxer->audio->id == -1) demuxer->audio->id=best_audio;if(!video_streams){    if(!audio_streams){	mp_msg(MSGT_HEADER,MSGL_ERR,MSGTR_MPDEMUX_ASFHDR_AudioVideoHeaderNotFound);	return 0;     }    demuxer->video->id=-2; // audio-only} else if (best_video > 0 && demuxer->video->id == -1) demuxer->video->id = best_video;#if 0if( 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);}#endifreturn 1;len_err_out:  mp_msg(MSGT_HEADER, MSGL_FATAL, MSGTR_MPDEMUX_ASFHDR_InvalidLengthInASFHeader);err_out:  if (hdr) free(hdr);  if (streams) free(streams);  return 0;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?