Cvirtual_binary Caud_file::decode() { Cvirtual_binary d; int cb_audio = get_cb_sample() * get_c_samples(); switch (header().compression) { case 1: { byte* w = d.write_start(cb_audio); for (int chunk_i = 0; w != d.data_end(); chunk_i++) { const t_aud_chunk_header& header = *get_chunk_header(chunk_i); aud_decode_ws_chunk(get_chunk_data(chunk_i), reinterpret_cast<char*>(w), header.size_in, header.size_out); w += header.size_out; } } break; case 0x63: { aud_decode decode; decode.init(); byte* w = d.write_start(cb_audio); for (int chunk_i = 0; w != d.data_end(); chunk_i++) { const t_aud_chunk_header* header = get_chunk_header(chunk_i); if (!header) break; decode.decode_chunk(get_chunk_data(chunk_i), reinterpret_cast<short*>(w), header->size_out / get_cb_sample()); w += header->size_out; } } break; } return d; }
static int handle_chunk_type(MMSHContext *mmsh) { MMSContext *mms = &mmsh->mms; int res, len = 0; ChunkType chunk_type; chunk_type = get_chunk_header(mmsh, &len); switch (chunk_type) { case CHUNK_TYPE_END: mmsh->chunk_seq = 0; av_log(NULL, AV_LOG_ERROR, "Stream ended!\n"); return AVERROR(EIO); case CHUNK_TYPE_STREAM_CHANGE: mms->header_parsed = 0; if (res = get_http_header_data(mmsh)) { av_log(NULL, AV_LOG_ERROR,"Stream changed! Failed to get new header!\n"); return res; } break; case CHUNK_TYPE_DATA: return read_data_packet(mmsh, len); default: av_log(NULL, AV_LOG_ERROR, "Recv other type packet %d\n", chunk_type); return AVERROR_INVALIDDATA; } return 0; }
static int get_http_header_data(MMSHContext *mmsh) { MMSContext *mms = &mmsh->mms; int res, len; ChunkType chunk_type; for (;;) { len = 0; res = chunk_type = get_chunk_header(mmsh, &len); if (res < 0) { return res; } else if (chunk_type == CHUNK_TYPE_ASF_HEADER){ // get asf header and stored it if (!mms->header_parsed) { if (mms->asf_header) { if (len != mms->asf_header_size) { mms->asf_header_size = len; av_dlog(NULL, "Header len changed from %d to %d\n", mms->asf_header_size, len); av_freep(&mms->asf_header); } } mms->asf_header = av_mallocz(len); if (!mms->asf_header) { return AVERROR(ENOMEM); } mms->asf_header_size = len; } if (len > mms->asf_header_size) { av_log(NULL, AV_LOG_ERROR, "Asf header packet len = %d exceed the asf header buf size %d\n", len, mms->asf_header_size); return AVERROR(EIO); } res = url_read_complete(mms->mms_hd, mms->asf_header, len); if (res != len) { av_log(NULL, AV_LOG_ERROR, "Recv asf header data len %d != expected len %d\n", res, len); return AVERROR(EIO); } mms->asf_header_size = len; if (!mms->header_parsed) { res = ff_mms_asf_header_parser(mms); mms->header_parsed = 1; return res; } } else if (chunk_type == CHUNK_TYPE_DATA) { // read data packet and do padding return read_data_packet(mmsh, len); } else { if (len) { if (len > sizeof(mms->in_buffer)) { av_log(NULL, AV_LOG_ERROR, "Other packet len = %d exceed the in_buffer size %zu\n", len, sizeof(mms->in_buffer)); return AVERROR(EIO); } res = url_read_complete(mms->mms_hd, mms->in_buffer, len); if (res != len) { av_log(NULL, AV_LOG_ERROR, "Read other chunk type data failed!\n"); return AVERROR(EIO); } else { av_dlog(NULL, "Skip chunk type %d \n", chunk_type); continue; } } } } return 0; }
const byte* Caud_file::get_chunk_data(int i) { return reinterpret_cast<const byte*>(get_chunk_header(i)) + sizeof(t_aud_chunk_header); }