int real_get_rdt_chunk(rtsp_t *rtsp_session, char **buffer, int rdt_rawdata) { int n=1; uint8_t header[8]; rmff_pheader_t ph; int size; int flags1, flags2; int unknown1; uint32_t ts; static uint32_t prev_ts = -1; static int prev_stream_number = -1; n=rtsp_read_data(rtsp_session, header, 8); if (n<8) return 0; if (header[0] != 0x24) { mp_msg(MSGT_STREAM, MSGL_WARN, "realrtsp: rdt chunk not recognized: got 0x%02x\n", header[0]); return 0; } /* header[1] is channel, normally 0, ignored */ size=(header[2]<<8)+header[3]; flags1=header[4]; if ((flags1 & 0xc0) != 0x40) { #ifdef LOG printf("got flags1: 0x%02x\n",flags1); #endif if(header[6] == 0x06) { // eof packet rtsp_read_data(rtsp_session, header, 7); // Skip the rest of the eof packet /* Some files have short auxiliary streams, we must ignore eof packets * for these streams to avoid premature eof. * Now the code declares eof only if the stream with id == 0 gets eof * (old code was: eof on the first eof packet received). */ if(flags1 & 0x7c) // ignore eof for streams with id != 0 return 0; mp_msg(MSGT_STREAM, MSGL_INFO, "realrtsp: Stream EOF detected\n"); return -1; } header[0]=header[5]; header[1]=header[6]; header[2]=header[7]; n=rtsp_read_data(rtsp_session, header+3, 5); if (n<5) return 0; #ifdef LOG printf("ignoring bytes:\n"); hexdump(header, 8); #endif n=rtsp_read_data(rtsp_session, header+4, 4); if (n<4) return 0; flags1=header[4]; size-=9; } flags2=header[7]; // header[5..6] == frame number in stream unknown1=(header[5]<<16)+(header[6]<<8)+(header[7]); n=rtsp_read_data(rtsp_session, header, 6); if (n<6) return 0; ts=AV_RB32(header); #ifdef LOG printf("ts: %u, size: %u, flags: 0x%02x, unknown values: 0x%06x 0x%02x 0x%02x\n", ts, size, flags1, unknown1, header[4], header[5]); #endif size+=2; ph.object_version=0; ph.length=size; ph.stream_number=(flags1>>1)&0x1f; ph.timestamp=ts; ph.reserved=0; if ((flags2&1) == 0 && (prev_ts != ts || prev_stream_number != ph.stream_number)) { prev_ts = ts; prev_stream_number = ph.stream_number; ph.flags=2; } else ph.flags=0; *buffer = xbuffer_ensure_size(*buffer, 12+size); if(rdt_rawdata) { if (size < 12) return 0; n=rtsp_read_data(rtsp_session, *buffer, size-12); return (n <= 0) ? 0 : n; } rmff_dump_pheader(&ph, *buffer); if (size < 12) return 0; size-=12; n=rtsp_read_data(rtsp_session, (*buffer)+12, size); return (n <= 0) ? 0 : n+12; }
static int real_process_media_packet(struct stream_t *stream,uint8_t *header, uint8_t *buffer,size_t max_size) { int ret = 0; struct stream_ctrl_t *stream_ctrl = stream->stream_ctrl; struct rmff_pheader_t ph = {0}; int size = 0; int seq = 0; int flags1 = 0,flags2 = 0; uint32_t ts = 0; if(header[0] != 0x24) { display(MSDL_ERR,"wrong rdt magic : [0x%02x]\n",header[0]); /* dump header*/ dbgdump(header,8); display(MSDL_DBG,"\n"); goto failed; } size = (header[1] << 16) + (header[2] << 8) + header[3]; flags1 = header[4]; if((flags1!=0x40) && (flags1!=0x42)) { display(MSDL_DBG,"wrong rdt flags1 : [0x%02x]\n",flags1); if(header[6] == 0x06) { display(MSDL_DBG,"got end of stream packet\n"); stream_ctrl->status = STREAMING_FINISHED; return 0; } header[0] = header[5]; header[1] = header[6]; header[2] = header[7]; ret = read_data(stream,header + 3,5); if(ret < 5) goto failed; ret = read_data(stream,header + 4,4); if(ret < 4) goto failed; flags1 = header[4]; size -= 9; } flags2 = header[7]; seq = (header[5] << 8) + header[6]; ret = read_data(stream,header,6); if(ret < 6) goto failed; ts = get32_be(header); stream_ctrl->packet_count++; display(MSDL_DBG,"ts:%u size:%u, flags1:0x%02x, seq:%d, flags2:%x\n", ts,size,flags1,seq,flags2); size += 2; ph.object_version = 0; ph.length = size; ph.stream_number = (flags1>>1) & 1; ph.timestamp = ts; ph.reserved = 0; if((flags2 & 1) == 0 && (stream_ctrl->rtsp_ctrl->prev_ts != ts || stream_ctrl->rtsp_ctrl->prev_stream_number != ph.stream_number)) { stream_ctrl->rtsp_ctrl->prev_ts = ts; stream_ctrl->rtsp_ctrl->prev_stream_number = ph.stream_number; ph.flags = 2; } else { ph.flags = 0; } /* * Keep Alive SET_PARAMETER */ /*if(!(stream_ctrl->packet_count % 200)) { struct rtsp_header_t *rtsp_hdr; rtsp_hdr = new_rtsp_header_with_standard_fields(stream_ctrl->rtsp_ctrl); if(stream->dlopts->bandwidth) { char *buffer = xmalloc(BUFSIZE_1K); snprintf(buffer,BUFSIZE_1K - 1, "SetDeliveryBandwidth: Bandwidth=%d;BackOff=0",stream->dlopts->bandwidth); rtsp_set_field(rtsp_hdr,buffer); free(buffer); } rtsp_request_set_parameter(rtsp_hdr,stream_ctrl->rtsp_ctrl->mrl); rtsp_send_request_and_free(stream,rtsp_hdr); }*/ /* if buffering, do special thing */ if(stream_ctrl->status == STREAMING_RESUME_BUFFERING) { display(MSDL_DBG, "target ts: %d [0x%x], current packet ts: %d [0x%x]\n", stream_ctrl->rtsp_ctrl->resume_start_ts, stream_ctrl->rtsp_ctrl->resume_start_ts, ph.timestamp,ph.timestamp); if(ph.timestamp == stream_ctrl->rtsp_ctrl->resume_start_ts) { stream_ctrl->status = STREAMING_DOWNLOADING; /* fallthrouh */ } else { int ret = 0; ret = read_data(stream,stream_ctrl->write_buffer,size - 12); /* trash data */ if(ret <= 0) goto failed; return 0; } } if(max_size > size) { /* all data can go to buffer --> just do it!! */ rmff_dump_pheader(&ph,buffer); size -= 12; ret = read_data(stream,buffer + 12,size); if(ret <= 0) goto failed; return ret + 12; } else { /* buffer is not enough.. copy max_size data to buffer and the rest goes to netsock->buffer. */ rmff_dump_pheader(&ph,stream_ctrl->write_buffer); ret = read_data(stream,stream_ctrl->write_buffer + 12,size - 12); if(ret <= 0) goto failed; /* it is guranteed that netsock->buffer is empty when it comes here! --> reset stream_ctrl->write_pos and so on... */ memcpy(buffer,stream_ctrl->write_buffer,max_size); stream_ctrl->write_data_len = size - max_size; stream_ctrl->write_pos = max_size; return max_size; } failed: return -1; }