Mercurial > mplayer.hg
changeset 1001:876c3edc2fa9
Continue implementation of ASF streaming.
author | bertrand |
---|---|
date | Mon, 04 Jun 2001 17:54:59 +0000 |
parents | 40b11384693b |
children | f035bd1f2749 |
files | asf_streaming.c |
diffstat | 1 files changed, 120 insertions(+), 38 deletions(-) [+] |
line wrap: on
line diff
--- a/asf_streaming.c Mon Jun 04 17:54:04 2001 +0000 +++ b/asf_streaming.c Mon Jun 04 17:54:59 2001 +0000 @@ -2,50 +2,84 @@ #include <stdlib.h> #include <string.h> -#include "asf.h" #include "url.h" #include "http.h" +#include "asf.h" #include "network.h" -#define BUFFER_SIZE 2048 +#include "stream.h" +#include "demuxer.h" -const char *temp_response = - "HTTP/1.0 200 OK\r\n" - "Date: Tue, 20 Mar 2001 11:40:35 GMT\r\n" - "Content-Type: application/octet-stream\r\n" - "Server: Cougar 4.1.0.3920\r\n" - "Cache-Control: no-cache\r\n" - "Pragma: no-cache, client-id=290092, features=\"broadcast\"\r\n" -/* "Pragma: no-cache\r\n" - "Pragma: client-id=290092\r\n" - "Pragma: features=\"broadcast\"\r\n" -*/ "\r\n"; +extern demuxer_t *demuxer; static ASF_StreamType_e streaming_type = ASF_Unknown_e; -void -asf_streaming(char *data, int length) { +int +asf_http_streaming_read( streaming_ctrl_t *streaming_ctrl ) { + char *buffer; + int drop_packet; + int ret; +printf("asf_streaming_read\n"); + ret = asf_streaming( streaming_ctrl->buffer->buffer, streaming_ctrl->buffer->length, &drop_packet ); +printf("ret: %d\n", ret); + if( ret<0 ) return -1; + if( ret>streaming_ctrl->buffer->length ) return 0; + buffer = (char*)malloc(ret); + if( buffer==NULL ) { + printf("Memory allocation failed\n"); + return -1; + } +printf("buffer length: %d\n", streaming_ctrl->buffer->length ); + net_fifo_pop( streaming_ctrl->buffer, buffer, ret ); +printf(" pop: 0x%02X\n", *((unsigned int*)buffer) ); +printf("buffer length: %d\n", streaming_ctrl->buffer->length ); +printf("0x%02X\n", *((unsigned int*)(buffer+sizeof(ASF_stream_chunck_t))) ); + if( !drop_packet ) { + write( streaming_ctrl->fd_pipe_in, buffer+sizeof(ASF_stream_chunck_t), ret-sizeof(ASF_stream_chunck_t) ); + } + free( buffer ); + return ret; +} + +int +asf_streaming(char *data, int length, int *drop_packet ) { ASF_stream_chunck_t *stream_chunck=(ASF_stream_chunck_t*)data; printf("ASF stream chunck size=%d\n", stream_chunck->size); +printf("length: %d\n", length ); +printf("0x%02X\n", stream_chunck->type ); + + if( drop_packet!=NULL ) *drop_packet = 0; + if( data==NULL || length<=0 ) return -1; if( stream_chunck->size<8 ) { printf("Ahhhh, stream_chunck size is too small: %d\n", stream_chunck->size); - return; + return -1; } if( stream_chunck->size!=stream_chunck->size_confirm ) { printf("size_confirm mismatch!: %d %d\n", stream_chunck->size, stream_chunck->size_confirm); - return; + return -1; } + printf(" type: 0x%02X\n", stream_chunck->type ); + printf(" size: %d (0x%02X)\n", stream_chunck->size, stream_chunck->size ); + printf(" sequence_number: 0x%04X\n", stream_chunck->sequence_number ); + printf(" unknown: 0x%02X\n", stream_chunck->unknown ); + printf(" size_confirm: 0x%02X\n", stream_chunck->size_confirm ); + + switch(stream_chunck->type) { case 0x4324: // Clear ASF configuration printf("=====> Clearing ASF stream configuration!\n"); + if( drop_packet!=NULL ) *drop_packet = 1; + return stream_chunck->size; break; case 0x4424: // Data follows printf("=====> Data follows\n"); break; case 0x4524: // Transfer complete printf("=====> Transfer complete\n"); + if( drop_packet!=NULL ) *drop_packet = 1; + return stream_chunck->size; break; case 0x4824: // ASF header chunk follows printf("=====> ASF header chunk follows\n"); @@ -53,6 +87,7 @@ default: printf("=====> Unknown stream type 0x%x\n", stream_chunck->type ); } + return stream_chunck->size+4; } int @@ -60,13 +95,13 @@ if( content_type==NULL ) return ASF_Unknown_e; if( !strcasecmp(content_type, "application/octet-stream") ) { if( features==NULL ) { - printf("=====> Prerecorded\n"); + printf("=====> ASF Prerecorded\n"); return ASF_Prerecorded_e; } else if( strstr(features, "broadcast")) { - printf("=====> Live stream\n"); + printf("=====> ASF Live stream\n"); return ASF_Live_e; } else { - printf("=====> Prerecorded\n"); + printf("=====> ASF Prerecorded\n"); return ASF_Prerecorded_e; } } else { @@ -77,25 +112,26 @@ (!strcasecmp(content_type, "video/x-ms-wvx")) || (!strcasecmp(content_type, "video/x-ms-wmv")) || (!strcasecmp(content_type, "video/x-ms-wma")) ) { - printf("=====> Redirector\n"); + printf("=====> ASF Redirector\n"); return ASF_Redirector_e; } else { - printf("=====> unknown content-type: %s\n", content_type ); + printf("=====> ASF unknown content-type: %s\n", content_type ); return ASF_Unknown_e; } } return ASF_Unknown_e; } -//void asf_http_request(stream_t *stream, URL_t *url) { HTTP_header_t * asf_http_request(URL_t *url) { HTTP_header_t *http_hdr; char str[250]; + char *ptr; char *request; + int i; int offset_hi=0, offset_lo=0, req_nb=1, length=0; - int asf_nb_stream=1; // FIXME + int asf_nb_stream; // Common header for all requests. http_hdr = http_new_header(); @@ -114,9 +150,28 @@ case ASF_Live_e: case ASF_Prerecorded_e: http_set_field( http_hdr, "Pragma: xPlayStrm=1" ); + ptr = str; + ptr += sprintf( ptr, "Pragma: stream-switch-entry="); + for( i=0, asf_nb_stream=0 ; i<256 ; i++ ) { + // FIXME START + if( demuxer==NULL ) { + ptr += sprintf( ptr, " ffff:1:0" ); + asf_nb_stream = 1; + break; + } + // FIXME END + if( demuxer->a_streams[i] ) { + ptr += sprintf( ptr, " ffff:%d:0", i ); + asf_nb_stream++; + } + if( demuxer->v_streams[i] ) { + ptr += sprintf( ptr, " ffff:%d:0", i ); + asf_nb_stream++; + } + } + http_set_field( http_hdr, str ); sprintf( str, "Pragma: stream-switch-count=%d", asf_nb_stream ); http_set_field( http_hdr, str ); - http_set_field( http_hdr, "Pragma: stream-switch-entry=ffff:1:0" ); // FIXME break; case ASF_Redirector_e: break; @@ -179,7 +234,7 @@ streaming_type = asf_http_streaming_type( content_type, features ); if( http_hdr->body_size>0 ) { - asf_streaming( http_hdr->body, http_hdr->body_size ); + asf_streaming( http_hdr->body, http_hdr->body_size, NULL); } return 0; @@ -196,69 +251,96 @@ } int -asf_http_streaming_start( URL_t **url_ref ) { +asf_http_streaming_start( streaming_ctrl_t *streaming_ctrl ) { HTTP_header_t *http_hdr=NULL; URL_t *url_next=NULL; - URL_t *url=*url_ref; + URL_t *url = *(streaming_ctrl->url); char buffer[BUFFER_SIZE]; int i; - int fd=-1; + int fd = streaming_ctrl->fd_net; int done=1; + +streaming_type = ASF_Live_e; do { if( fd>0 ) close( fd ); + fd = connect2Server( url->hostname, url->port ); if( fd<0 ) return -1; http_hdr = asf_http_request( url ); -//printf("[%s]\n", http_hdr->buffer ); +printf("[%s]\n", http_hdr->buffer ); write( fd, http_hdr->buffer, http_hdr->buffer_size ); - http_free( http_hdr ); +// http_free( http_hdr ); http_hdr = http_new_header(); do { - i = read( fd, buffer, BUFFER_SIZE ); + i = readFromServer( fd, buffer, BUFFER_SIZE ); printf("read: %d\n", i ); + if( i<0 ) { + perror("read"); + http_free( http_hdr ); + return -1; + } http_response_append( http_hdr, buffer, i ); } while( !http_is_header_entired( http_hdr ) ); //http_hdr->buffer[http_hdr->buffer_len]='\0'; //printf("[%s]\n", http_hdr->buffer ); if( asf_http_parse_response(http_hdr)<0 ) { printf("Failed to parse header\n"); + http_free( http_hdr ); return -1; } - - switch(streaming_type) { + switch( streaming_type ) { case ASF_Live_e: case ASF_Prerecorded_e: - if( http_hdr->body_size==0 ) { - i = read( fd, buffer, BUFFER_SIZE ); + if( http_hdr->body_size>0 ) { +printf("--- 0x%02X\n", streaming_ctrl->buffer ); + net_fifo_push( streaming_ctrl->buffer, http_hdr->body, http_hdr->body_size ); + } else { + ASF_stream_chunck_t *ptr; + int ret; + i = readFromServer( fd, buffer, sizeof(ASF_stream_chunck_t) ); printf("read: %d\n", i ); - asf_streaming( buffer, i ); + ret = asf_streaming( buffer, i, NULL ); + net_fifo_push( streaming_ctrl->buffer, buffer, i ); + ptr = (ASF_stream_chunck_t*)buffer; + if( ret==ptr->size ) { + } } +// done = 0; break; case ASF_Redirector_e: url_next = asf_http_ASX_redirect( http_hdr ); if( url_next==NULL ) { printf("Failed to parse ASX file\n"); close(fd); + http_free( http_hdr ); return -1; } if( url_next->port==0 ) url_next->port=80; url_free( url ); url = url_next; - *url_ref = url_next; + *(streaming_ctrl->url) = url_next; url_next = NULL; break; case ASF_Unknown_e: default: printf("Unknown ASF streaming type\n"); close(fd); + http_free( http_hdr ); return -1; } // Check if we got a redirect. } while(!done); + streaming_ctrl->fd_net = fd; + streaming_ctrl->streaming_read = asf_http_streaming_read; + streaming_ctrl->prebuffer_size = 10000; + streaming_ctrl->buffering = 1; + streaming_ctrl->status = streaming_playing_e; + + http_free( http_hdr ); return fd; }