/* * parse asf_data_packet (@packet) and put the data in adph */ int asf_parse_data_packet_header(uint8_t *packet,struct asf_data_packet_header_t *adph) { uint8_t ecd_flags = packet[0]; uint8_t length_type_flags = 0; uint8_t property_flags = 0; int ppi_offset = 0; int next_offset = 0; /* length type dependent stuff */ const int length_type_table[4] = {0,1,2,4}; adph->ecd.error_correction_data_length = ecd_flags & 0x0f; adph->ecd.opaque_data_present = (ecd_flags >> 4) & 0x01; adph->ecd.error_correction_length_type = (ecd_flags >> 5) & 0x03; adph->ecd.error_correction_present = (ecd_flags >> 7) & 0x01; if(adph->ecd.error_correction_present) { ppi_offset = 1 + adph->ecd.error_correction_data_length; } else { ppi_offset = 1; } length_type_flags = packet[ppi_offset]; property_flags = packet[ppi_offset + 1]; adph->ppi.multiple_payloads_present = length_type_flags & 0x01; adph->ppi.sequence_type = (length_type_flags >> 1) & 0x03; adph->ppi.padding_length_type = (length_type_flags >> 3) & 0x03; adph->ppi.packet_length_type = (length_type_flags >> 5) & 0x03; adph->ppi.error_correction_present = (length_type_flags >> 7) & 0x01; adph->ppi.replicated_data_length_type = property_flags & 0x03; adph->ppi.offset_into_media_object_length_type = (property_flags >> 2) & 0x03; adph->ppi.media_object_number_length_type = (property_flags >> 4) & 0x03; adph->ppi.stream_number_length_type = (property_flags >> 6) & 0x03; next_offset = ppi_offset + 2; /* packet length */ adph->ppi.packet_length = getnb_le(packet + next_offset,length_type_table[adph->ppi.packet_length_type]); next_offset += length_type_table[adph->ppi.packet_length_type]; /* sequence */ adph->ppi.sequence = getnb_le(packet + next_offset,length_type_table[adph->ppi.sequence_type]); next_offset += length_type_table[adph->ppi.sequence_type]; /* padding length */ adph->ppi.padding_length = getnb_le(packet + next_offset,length_type_table[adph->ppi.padding_length_type]); next_offset += length_type_table[adph->ppi.padding_length_type]; adph->ppi.send_time = get32_le(packet + next_offset); next_offset += sizeof(uint32_t); adph->ppi.duration = get16_le(packet + next_offset); next_offset += sizeof(uint16_t); return next_offset; }
static int dvms_read_header(sox_format_t * ft, struct dvms_header *hdr) { unsigned char hdrbuf[DVMS_HEADER_LEN]; unsigned char *pch = hdrbuf; int i; unsigned sum; if (lsx_readbuf(ft, hdrbuf, sizeof(hdrbuf)) != sizeof(hdrbuf)) { return (SOX_EOF); } for(i = sizeof(hdrbuf), sum = 0; i > /*2*/3; i--) /* Deti bug */ sum += *pch++; pch = hdrbuf; memcpy(hdr->Filename, pch, sizeof(hdr->Filename)); pch += sizeof(hdr->Filename); hdr->Id = get16_le(&pch); hdr->State = get16_le(&pch); hdr->Unixtime = get32_le(&pch); hdr->Usender = get16_le(&pch); hdr->Ureceiver = get16_le(&pch); hdr->Length = get32_le(&pch); hdr->Srate = get16_le(&pch); hdr->Days = get16_le(&pch); hdr->Custom1 = get16_le(&pch); hdr->Custom2 = get16_le(&pch); memcpy(hdr->Info, pch, sizeof(hdr->Info)); pch += sizeof(hdr->Info); memcpy(hdr->extend, pch, sizeof(hdr->extend)); pch += sizeof(hdr->extend); hdr->Crc = get16_le(&pch); if (sum != hdr->Crc) { lsx_report("DVMS header checksum error, read %u, calculated %u", hdr->Crc, sum); return (SOX_EOF); } return (SOX_SUCCESS); }
/* * choose best audio and video streams, below bw. * 'header' is an asf header, and 'asf_header_size' is its size. * the result will be in 'streams' * return value: 1 ... success * -1 ... failed */ int asf_choose_best_streams(const uint8_t *header, int asf_header_size, int bw, struct asf_streams_t *streams) { int i = 0,pos = 0,start = 0; int *v_rates = NULL, *a_rates = NULL; int v_rate = 0, a_rate = 0, v_idx = -1, a_idx = -1; /* header is entire ASF header, including very first asf_header_t. */ pos = sizeof(struct asf_header_t); start = pos; /* choose best (fastest) streams */ while((pos = find_asf_guid(header,pos,asf_stream_header_guid,asf_header_size)) >= 0) { struct asf_stream_header_t *streamh = (struct asf_stream_header_t *)(header + pos); pos += sizeof(struct asf_stream_header_t); if(pos > asf_header_size) /* error */ return -1; /* get ASF GUID PREFIX (first 4 byte of GUID) */ switch(get32_le(streamh->type)) { case ASF_AUDIO_STREAM: /* audio stream */ display(MSDL_VER,"audio stream detected!!!!\n"); if(streams->audio_streams == NULL) { /* no audio stream registerd yet */ streams->audio_streams = (int *)xmalloc(sizeof(int)); streams->n_audio = 1; } else { /* more audio streams.!! */ streams->n_audio++; streams->audio_streams = (int *)xrealloc(streams->audio_streams, streams->n_audio * sizeof(int)); } streams->audio_streams[streams->n_audio - 1] = le2me_16(streamh->stream_no); break; case ASF_VIDEO_STREAM: /* video streams */ display(MSDL_VER,"video stream detected!!!!\n"); if(streams->video_streams == NULL) { /* no video stream registerd yet */ streams->video_streams = (int *)xmalloc(sizeof(int)); streams->n_video = 1; } else { /* more video streams.!! */ streams->n_video++; streams->video_streams = (int *)xrealloc(streams->video_streams, streams->n_video * sizeof(int)); } streams->video_streams[streams->n_video - 1] = le2me_16(streamh->stream_no); break; case ASF_COMMAND_MEDIA_STREAM: /* Command media stream... whatever*/ display(MSDL_VER,"Command media stream detected, but ignore this.\n"); break; case ASF_FILE_TRANSFER_MEDIA_STREAM: /* File transfer media stream... I don't know what the heck this is.*/ display(MSDL_VER,"File transfer stream detected, but ignore this.\n"); break; } } a_rates = (int *)xmalloc(streams->n_audio * sizeof(int)); v_rates = (int *)xmalloc(streams->n_video * sizeof(int)); pos = find_asf_guid(header,start,asf_stream_group_guid,asf_header_size); if(pos >= 0) { /* stream bitrate proterties object */ int stream_count = 0; uint8_t *ptr = (uint8_t *)header + pos; display(MSDL_VER,"stream bitrate properties object\n"); stream_count = get16_le(ptr); /* little endian. */ ptr += sizeof(uint16_t); if(ptr > header + asf_header_size) goto failed; display(MSDL_VER,"stream count = [0x%x] [%u]\n",stream_count,stream_count); display(MSDL_VER,"audio streams: %d, video streams: %d\n", streams->n_audio,streams->n_video); for(i = 0; i < stream_count; i++) { uint32_t rate = 0; int id = 0; int j = 0; id = get16_le(ptr); ptr += sizeof(uint16_t); if(ptr > header + asf_header_size) goto failed; rate = get32_le(ptr); ptr += sizeof(uint32_t); if(ptr > header + asf_header_size) goto failed; display(MSDL_VER, "stream_id = [0x%x] [%u]\n" "max bitrate = [0x%x] [%u]\n", id,id,rate,rate); for(j = 0; j < streams->n_audio; j++) { if(id == streams->audio_streams[j]) { display(MSDL_VER,"is audio stream\n"); a_rates[j] = rate; break; } } for(j = 0; j < streams->n_video; j++) { if(id == streams->video_streams[j]) { display(MSDL_VER,"is video stream\n"); v_rates[j] = rate; break; } } } } /* just to make sure bw is not Zero! */ if(bw == 0) { bw = INT_MAX_BANDWIDTH; } if(streams->n_audio) { /* find lowest-bitrate audio stream */ a_rate = a_rates[0]; a_idx = 0; for(i = 0; i < streams->n_audio; i++) { if(a_rates[i] < a_rate) { a_rate = a_rates[i]; a_idx = i; } } if(max_idx(streams->n_video,v_rates,bw - a_rate) < 0) { /* both audio and video are not possible, try video only next */ a_idx = -1; a_rate = 0; } } /* find best video stream */ v_idx = max_idx(streams->n_video,v_rates,bw - a_rate); if(v_idx >= 0) { v_rate = v_rates[v_idx]; } /* find best auido stream */ a_idx = max_idx(streams->n_audio,a_rates,bw - v_rate); free(v_rates); v_rates = NULL; free(a_rates); a_rates = NULL; if(a_idx < 0 && v_idx < 0) { display(MSDL_ERR,"bandwidth too low ... cannot get streams."); return -1; } if(a_idx >= 0) { streams->audio_id = streams->audio_streams[a_idx]; } else if(streams->n_audio) { display(MSDL_ERR,"Bandwidth too too small so deselected audio....sad.\n"); } if(v_idx >= 0) { streams->video_id = streams->video_streams[v_idx]; } else if(streams->n_video) { display(MSDL_ERR,"Bandwidth too too small so deselected video....sad.\n"); } return 1; failed: free(v_rates); free(a_rates); return -1; }