/** Read ASF data through the protocol. */ static int mms_read(URLContext *h, uint8_t *buf, int size) { /* TODO: see tcp.c:tcp_read() about a possible timeout scheme */ MMSTContext *mmst = h->priv_data; MMSContext *mms = &mmst->mms; int result = 0; do { if(mms->asf_header_read_size < mms->asf_header_size) { /* Read from ASF header buffer */ result = ff_mms_read_header(mms, buf, size); } else if(mms->remaining_in_len) { /* Read remaining packet data to buffer. * the result can not be zero because remaining_in_len is positive.*/ result = ff_mms_read_data(mms, buf, size); } else { /* Read from network */ int err = mms_safe_send_recv(mmst, NULL, SC_PKT_ASF_MEDIA); if (err == 0) { if(mms->remaining_in_len > mms->asf_packet_len) { av_log(NULL, AV_LOG_ERROR, "Incoming pktlen %d is larger than ASF pktsize %d\n", mms->remaining_in_len, mms->asf_packet_len); result = AVERROR(EIO); } else { // copy the data to the packet buffer. result = ff_mms_read_data(mms, buf, size); if (result == 0) { av_dlog(NULL, "read asf media paket size is zero!\n"); break; } } } else { av_dlog(NULL, "read packet error!\n"); break; } } } while(!result); // only return one packet. return result; }
/** Read ASF data through the protocol. */ static int mms_read(URLContext *h, uint8_t *buf, int size) { /* TODO: see tcp.c:tcp_read() about a possible timeout scheme */ MMSContext *mms = h->priv_data; int result = 0; /* Since we read the header at open(), this shouldn't be possible */ assert(mms->header_parsed); if (!mms->is_playing) { dprintf(NULL, "mms_read() before play().\n"); clear_stream_buffers(mms); result = mms_safe_send_recv(mms, send_stream_selection_request, SC_PKT_STREAM_ID_ACCEPTED); if (result) return result; // send media packet request result = mms_safe_send_recv(mms, send_media_packet_request, SC_PKT_MEDIA_PKT_FOLLOWS); if (result) { return result; } } return read_mms_packet(mms, buf, size); }
/** Read ASF data through the protocol. */ static int mms_read(URLContext *h, uint8_t *buf, int size) { /* TODO: see tcp.c:tcp_read() about a possible timeout scheme */ MMSContext *mms = h->priv_data; int result = 0; int size_to_copy; do { if(mms->asf_header_read_size < mms->asf_header_size) { /* Read from ASF header buffer */ size_to_copy= FFMIN(size, mms->asf_header_size - mms->asf_header_read_size); memcpy(buf, mms->asf_header + mms->asf_header_read_size, size_to_copy); mms->asf_header_read_size += size_to_copy; result += size_to_copy; dprintf(NULL, "Copied %d bytes from stored header. left: %d\n", size_to_copy, mms->asf_header_size - mms->asf_header_read_size); if (mms->asf_header_size == mms->asf_header_read_size) { av_freep(&mms->asf_header); } } else if(mms->remaining_in_len) { /* Read remaining packet data to buffer. * the result can not be zero because remaining_in_len is positive.*/ result = read_data(mms, buf, size); } else { /* Read from network */ int err = mms_safe_send_recv(mms, NULL, SC_PKT_ASF_MEDIA); if (err == 0) { if(mms->remaining_in_len>mms->asf_packet_len) { av_log(NULL, AV_LOG_ERROR, "Incoming pktlen %d is larger than ASF pktsize %d\n", mms->remaining_in_len, mms->asf_packet_len); result= AVERROR_IO; } else { // copy the data to the packet buffer. result = read_data(mms, buf, size); if (result == 0) { dprintf(NULL, "read asf media paket size is zero!\n"); break; } } } else { dprintf(NULL, "read packet error!\n"); break; } } } while(!result); // only return one packet. return result; }
/** Read at most one media packet (or a whole header). */ static int read_mms_packet(MMSContext *mms, uint8_t *buf, int buf_size) { int result = 0; int size_to_copy; do { if(mms->asf_header_read_size < mms->asf_header_size && !mms->is_playing) { /* Read from ASF header buffer */ size_to_copy= FFMIN(buf_size, mms->asf_header_size - mms->asf_header_read_size); memcpy(buf, mms->asf_header + mms->asf_header_read_size, size_to_copy); mms->asf_header_read_size += size_to_copy; result += size_to_copy; dprintf(NULL, "Copied %d bytes from stored header. left: %d\n", size_to_copy, mms->asf_header_size - mms->asf_header_read_size); if (mms->asf_header_size == mms->asf_header_read_size) { av_freep(&mms->asf_header); mms->is_playing = 1; } } else if(mms->remaining_in_len) { /* Read remaining packet data to buffer. * the result can not be zero because remaining_in_len is positive.*/ result = read_data(mms, buf, buf_size); } else { /* Read from network */ int err = mms_safe_send_recv(mms, NULL, SC_PKT_ASF_MEDIA); if (err == 0) { if(mms->remaining_in_len>mms->asf_packet_len) { dprintf(NULL, "Incoming packet" "larger than the asf packet size stated (%d>%d)\n", mms->remaining_in_len, mms->asf_packet_len); result= AVERROR_IO; } else { // copy the data to the packet buffer. result = read_data(mms, buf, buf_size); if (result == 0) { dprintf(NULL, "read asf media paket size is zero!\n"); break; } } } else { dprintf(NULL, "read packet error!\n"); break; } } } while(!result); // only return one packet. return result; }
static int mms_open(URLContext *h, const char *uri, int flags) { MMSTContext *mmst; MMSContext *mms; int port, err; char tcpname[256]; h->is_streamed = 1; mmst = h->priv_data = av_mallocz(sizeof(MMSTContext)); if (!h->priv_data) return AVERROR(ENOMEM); mms = &mmst->mms; // only for MMS over TCP, so set proto = NULL av_url_split(NULL, 0, NULL, 0, mmst->host, sizeof(mmst->host), &port, mmst->path, sizeof(mmst->path), uri); if(port < 0) port = 1755; // defaut mms protocol port // establish tcp connection. ff_url_join(tcpname, sizeof(tcpname), "tcp", NULL, mmst->host, port, NULL); err = ffurl_open(&mms->mms_hd, tcpname, AVIO_RDWR); if (err) goto fail; mmst->packet_id = 3; // default, initial value. mmst->header_packet_id = 2; // default, initial value. err = mms_safe_send_recv(mmst, send_startup_packet, SC_PKT_CLIENT_ACCEPTED); if (err) goto fail; err = mms_safe_send_recv(mmst, send_time_test_data, SC_PKT_TIMING_TEST_REPLY); if (err) goto fail; err = mms_safe_send_recv(mmst, send_protocol_select, SC_PKT_PROTOCOL_ACCEPTED); if (err) goto fail; err = mms_safe_send_recv(mmst, send_media_file_request, SC_PKT_MEDIA_FILE_DETAILS); if (err) goto fail; err = mms_safe_send_recv(mmst, send_media_header_request, SC_PKT_HEADER_REQUEST_ACCEPTED); if (err) goto fail; err = mms_safe_send_recv(mmst, NULL, SC_PKT_ASF_HEADER); if (err) goto fail; if((mmst->incoming_flags != 0X08) && (mmst->incoming_flags != 0X0C)) { av_log(NULL, AV_LOG_ERROR, "The server does not support MMST (try MMSH or RTSP)\n"); err = AVERROR(EINVAL); goto fail; } err = ff_mms_asf_header_parser(mms); if (err) { av_dlog(NULL, "asf header parsed failed!\n"); goto fail; } mms->header_parsed = 1; if (!mms->asf_packet_len || !mms->stream_num) goto fail; clear_stream_buffers(mms); err = mms_safe_send_recv(mmst, send_stream_selection_request, SC_PKT_STREAM_ID_ACCEPTED); if (err) goto fail; // send media packet request err = mms_safe_send_recv(mmst, send_media_packet_request, SC_PKT_MEDIA_PKT_FOLLOWS); if (err) { goto fail; } av_dlog(NULL, "Leaving open (success)\n"); return 0; fail: mms_close(h); av_dlog(NULL, "Leaving open (failure: %d)\n", err); return err; }
static int mms_open(URLContext *h, const char *uri, int flags) { MMSContext *mms; int port, err; char tcpname[256]; h->is_streamed = 1; mms = h->priv_data = av_mallocz(sizeof(MMSContext)); if (!h->priv_data) return AVERROR(ENOMEM); // only for MMS over TCP, so set proto = NULL av_url_split(NULL, 0, NULL, 0, mms->host, sizeof(mms->host), &port, mms->path, sizeof(mms->path), uri); if(port<0) port = 1755; // defaut mms protocol port // establish tcp connection. ff_url_join(tcpname, sizeof(tcpname), "tcp", NULL, mms->host, port, NULL); err = url_open(&mms->mms_hd, tcpname, URL_RDWR); if (err) goto fail; mms->packet_id = 3; // default, initial value. mms->header_packet_id = 2; // default, initial value. err = mms_safe_send_recv(mms, send_startup_packet, SC_PKT_CLIENT_ACCEPTED); if (err) goto fail; err = mms_safe_send_recv(mms, send_time_test_data, SC_PKT_TIMING_TEST_REPLY); if (err) goto fail; err = mms_safe_send_recv(mms, send_protocol_select, SC_PKT_PROTOCOL_ACCEPTED); if (err) goto fail; err = mms_safe_send_recv(mms, send_media_file_request, SC_PKT_MEDIA_FILE_DETAILS); if (err) goto fail; err = mms_safe_send_recv(mms, send_media_header_request, SC_PKT_HEADER_REQUEST_ACCEPTED); if (err) goto fail; err = mms_safe_send_recv(mms, NULL, SC_PKT_ASF_HEADER); if (err) goto fail; if((mms->incoming_flags != 0X08) && (mms->incoming_flags != 0X0C)) goto fail; err = asf_header_parser(mms); if (err) { dprintf(NULL, "asf header parsed failed!\n"); goto fail; } mms->header_parsed = 1; if (!mms->asf_packet_len || !mms->stream_num) goto fail; dprintf(NULL, "Leaving open (success)\n"); return 0; fail: mms_close(h); dprintf(NULL, "Leaving open (failure: %d)\n", err); return err; }