📄 mmst.c
字号:
"packet length : %d bytes\n", asf_header_len,mmst_ctrl->hinfo->fileh->max_packet_size); stream_ctrl->packet_length = mmst_ctrl->hinfo->fileh->max_packet_size; mmst_ctrl->num_stream_ids = mmst_ctrl->hinfo->streams->n_audio + mmst_ctrl->hinfo->streams->n_video; /* * 0x33 command, not understood very well */ memset(buffer,0,mmst_ctrl->num_stream_ids * 6 + 2); pos = 0; display(MSDL_VER,"number of audio stream : %d, video stream = %d\n" "best audio stream : %d, video stream : %d\n", mmst_ctrl->hinfo->streams->n_audio, mmst_ctrl->hinfo->streams->n_video, mmst_ctrl->hinfo->streams->audio_id, mmst_ctrl->hinfo->streams->video_id); /* * chunkLen : 4bytes * MID : 4bytes * cStreamEntries : 4bytes (num of entries) * cStreamEntries : (variable, each 6 bytes) * * typedef struct { * WORD wSrcStreamNumber; * WORD wDstStreamNumber; * WORD wThinningLevel; * } STREAM_SWITCH_ENTRY; * */ pos = 0; for(i = 0 ; i < mmst_ctrl->hinfo->streams->n_audio; i++) { buffer[pos + 0] = 0xFF; buffer[pos + 1] = 0xFF; buffer[pos + 2] = mmst_ctrl->hinfo->streams->audio_streams[i]; buffer[pos + 3] = mmst_ctrl->hinfo->streams->audio_streams[i] >> 8; if(mmst_ctrl->hinfo->streams->audio_streams[i] == mmst_ctrl->hinfo->streams->audio_id) { display(MSDL_DBG,"enable audio stream[%d]\n",mmst_ctrl->hinfo->streams->audio_id); buffer[pos + 4] = 0x00; buffer[pos + 5] = 0x00; } else { display(MSDL_DBG,"disable audio stream[%d]\n",mmst_ctrl->hinfo->streams->audio_id); buffer[pos + 4] = 0x02; buffer[pos + 5] = 0x00; } pos += 6; } for(i = 0 ; i < mmst_ctrl->hinfo->streams->n_video; i++) { buffer[pos + 0] = 0xFF; buffer[pos + 1] = 0xFF; buffer[pos + 2] = mmst_ctrl->hinfo->streams->video_streams[i]; buffer[pos + 3] = mmst_ctrl->hinfo->streams->video_streams[i] >> 8; if(mmst_ctrl->hinfo->streams->video_streams[i] == mmst_ctrl->hinfo->streams->video_id) { display(MSDL_DBG,"enable video stream[%d]\n",mmst_ctrl->hinfo->streams->audio_id); buffer[pos + 4] = 0x00; buffer[pos + 5] = 0x00; } else { display(MSDL_DBG,"disable video stream[%d]\n",mmst_ctrl->hinfo->streams->audio_id); buffer[pos + 4] = 0x02; buffer[pos + 5] = 0x00; } pos += 6; } send_command(stream,0x33, mmst_ctrl->num_stream_ids, /* cStreamEntries */ buffer[0] | (buffer[1] << 8) | (buffer[2] <<16) | (buffer[3] <<24), /* dirty shift */ pos - 4, buffer + 4); mmst_get_command_packet(stream); /* * 0x07 command. includes ?session value and maximum media stream time */ memset(buffer,0,40); for(i = 8 ; i < 16 ; i++) { buffer[i] = 0xFF; } buffer[20] = 0x04; send_command(stream,0x07, 1, 0, 24, buffer); /** now everything is done, wait for media packets !!! **/ free(buffer); free(buffer2); /* set status */ stream_ctrl->status = STREAMING_DOWNLOADING; stream_ctrl->protocol = MMST; return 1; /* success */ failed: free(buffer); free(buffer2); return 0;}/* * get COMMAND PACKET ONLY , ignore data in commands. * data (media) packets are all ignored, as they are not expected. * should be used only in mmst_streaming_start */static int mmst_get_command_packet(struct stream_t *stream){ uint8_t *pre_header[8]; uint32_t packet_len; uint32_t command; uint8_t *combuf; while(1) { combuf = NULL; if(read_data(stream,pre_header,8) <= 0) { /* read_data() failed. */ goto failed; } if(read_data(stream,&packet_len,4) <= 0) { display(MSDL_ERR,"read_data for packet_len failed\n"); goto failed; } packet_len = get32_le(&packet_len) + 4; if(packet_len < 0 || BUF_SIZE < packet_len) { display(MSDL_ERR,"%x: invalid packet size\n",packet_len,BUF_SIZE); goto failed; } combuf = xmalloc(packet_len); if(read_data(stream,combuf,packet_len) <= 0) { /* error */ free(combuf); goto failed; } display(MSDL_DBG,"=-recv (command)-----------------------------------=\n"); dbgdump(combuf,packet_len); display(MSDL_DBG,"\n=--------------------------------------------------=\n"); command = get32_le(combuf + 24) & 0xFFFF; if(command == 0x1b) { send_command(stream,0x1b, 0, 0, 0, combuf); free(combuf); } else { free(combuf); break; } } return 0; failed: if(combuf) free(combuf); return -1;}/* * get each media packet. * * when media packet: get 'packet_len' bytes of data from sock, and store them to buffer. * if max_size was smaller(buffer was too small), the rest goes to * netsock->buffer. * * command packet: don't do anything to buffer. * * return value : positive value ... bytes written to 'buffer'. * 0 ... END OF FILE * -1 ... Error. */static int mmst_get_media_packet(struct stream_t *stream, uint8_t *buffer, size_t max_size){ struct stream_ctrl_t *stream_ctrl = stream->stream_ctrl; uint8_t pre_header[8]; uint32_t packet_len; uint32_t command; int ret; while (1) { stream_ctrl->write_data_len = 0; if(read_data(stream,pre_header,8) <= 0) { display(MSDL_ERR,"could not receive packet pre header\n"); goto failed; } if(pre_header[4] == 0x04) { /* media packet */ packet_len = get16_le(((uint8_t *)&pre_header) + 6) - 8; stream_ctrl->packet_count++; /* increment packet count */ if(packet_len < 0) { display(MSDL_ERR,"%d: invalid packet size\n",packet_len); goto failed; } if(stream_ctrl->packet_length <= max_size) { /* buffer is bigger than incoming packet (and padding) */ ret = read_data(stream, buffer, packet_len); if(ret < 0) { display(MSDL_ERR,"couldn't read from netwrok failed\n"); goto failed; } memset(buffer + ret, 0, stream_ctrl->packet_length - ret); /* padding */ ret = stream_ctrl->packet_length; } else { /* buffer is NOT big enough for incoming packet.. (and padding) */ ret = read_data(stream, stream_ctrl->write_buffer, packet_len); if(ret < 0) { display(MSDL_ERR,"couldn't read from netwrok failed\n"); goto failed; } /* this is OK because stream_ctrl->write_buffer is empty */ memset(stream_ctrl->write_buffer + packet_len, 0, /* padding */ stream_ctrl->packet_length - packet_len); memcpy(buffer,stream_ctrl->write_buffer, max_size); ret = stream_ctrl->write_pos = max_size; stream_ctrl->write_data_len = stream_ctrl->packet_length - max_size; } return ret; } else { /* command packet */ uint8_t *combuf; /* check command packet signiture */ if(get32_le(((uint8_t *)&pre_header) + 4) != 0xB00BFACE) { display(MSDL_ERR,"missing command signiture!\n"); goto failed; } if(read_data(stream, &packet_len,4) <= 0) { display(MSDL_ERR,"command packet length read failed\n"); goto failed; } packet_len = get32_le(&packet_len) + 4; if(packet_len < 0 || packet_len > BUF_SIZE) { display(MSDL_ERR,"%d: invalid packet size\n",packet_len); goto failed; } combuf = xmalloc(packet_len); /* get command packet */ if(read_data(stream, combuf, packet_len) <= 0) { display(MSDL_ERR,"command data read failed\n"); free(combuf); goto failed; } command = get32_le(combuf + 24) & 0xFFFF; if(command == 0x1B) { send_command(stream,0x1B, 0, 0, 0, combuf); } else if(command == 0x1E) { /* End Of Stream (EOS) */ stream_ctrl->status = STREAMING_FINISHED; free(combuf); return 0; /* End Of Stream!! */ } else if(command == 0x05) { ; /* wired packet, ignore this (not UNKNOWN) */ } else if(command == 0x21) { ; /* wired packet, ignroe this (not UNKNOWN) */ } else { display(MSDL_DBG,"unknown command %x (ignore this)\n",command); } free(combuf); } /* command packet */ } /* while(1) */ return 0; failed: return -1;}/* * read mms over http stream. filles buffer, and buffer size is 'size' * * read cached data from stream->stream_ctrl->write_buffer * check for to see if network access is necessary * get chunk(media packet) from network. * * return value: bytes written to buffer. */int mmst_streaming_read(struct stream_t *stream, uint8_t *buffer, size_t buffer_size){ struct stream_ctrl_t *stream_ctrl = stream->stream_ctrl; size_t pos = 0; /* how many bytes written to buffer. */ int ret = 0; if(stream_ctrl->write_data_len) { /* there are some data to copy in stream_ctrl->write_buffer */ if(buffer_size <= stream_ctrl->write_data_len) { /* buffer_size < stream_ctrl->write_data_len... fill buffer, and return. */ memcpy(buffer,stream_ctrl->write_buffer + stream_ctrl->write_pos, buffer_size); stream_ctrl->write_data_len -= buffer_size; stream_ctrl->write_pos += buffer_size; return buffer_size; } else { /* stream_ctrl->write_data_len < buffer_size, have to read from network. */ memcpy(buffer,stream_ctrl->write_buffer + stream_ctrl->write_pos, stream_ctrl->write_data_len); pos = stream_ctrl->write_data_len; /* and stream_ctrl->write_buffer is empty. */ stream_ctrl->write_data_len = 0; stream_ctrl->write_pos = 0; } } stream_ctrl->write_data_len = 0; stream_ctrl->write_pos = 0; if(stream_ctrl->status != STREAMING_FINISHED) { /* still have to get data from network. there are buffer_size - pos bytes to be filled (max) */ ret = mmst_get_media_packet(stream, buffer + pos, buffer_size - pos); } if(ret >= 0) { return ret + pos; } else { return -1; }}struct stream_t *mmst_streaming_init(){ struct stream_t *stream = streaming_init_common(); stream->stream_ctrl->mmst_ctrl = new_mmst_ctrl_t(); stream->start = mmst_streaming_start; stream->read = mmst_streaming_read; stream->close = mmst_streaming_close; return stream;}void mmst_streaming_close(struct stream_t *stream){ if(stream->netsock->sock > 0) { /* valid socket */ close(stream->netsock->sock); } free_mmst_ctrl_t(stream->stream_ctrl->mmst_ctrl); streaming_close_common(stream);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -