[FFmpeg-devel] [patch]MMS protocol over TCP
zhentan feng
spyfeng
Mon May 24 18:49:09 CEST 2010
Hi
On Mon, May 24, 2010 at 6:48 AM, Michael Niedermayer <michaelni at gmx.at>wrote:
> On Sun, May 23, 2010 at 11:16:23PM +0800, zhentan feng wrote:
> > Hi
> >
> > On Wed, May 19, 2010 at 7:48 AM, Michael Niedermayer <michaelni at gmx.at
> >wrote:
> >
> > > On Wed, May 12, 2010 at 12:11:37AM +0800, zhentan feng wrote:
> [...]
> > +/** 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_pos < mms->asf_header_size) {
> > + /* Read from ASF header buffer */
> > + size_to_copy= FFMIN(buf_size,
> > + mms->asf_header_size -
> mms->asf_header_read_pos);
> > + memcpy(buf, mms->asf_header + mms->asf_header_read_pos,
> size_to_copy);
> > + mms->asf_header_read_pos += 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_pos);
> > + av_freep(&mms->asf_header);
>
> this frees asf_header no matter how much or little has been consumed
> is that intended?
> it seems kinda odd as asf_header_read_pos is updated but the array is gone
> after this
>
>
yes, this is a possible bug. I fixed it.
and after consideration, mms->asf_header_read_pos is not necessary, so I use
a tmp variable instead of it.
>
> > + } 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 send_close_packet(MMSContext *mms)
> > +{
> > + start_command_packet(mms, CS_PKT_STREAM_CLOSE);
> > + insert_command_prefixes(mms, 1, 1);
> > +
> > + return send_command_packet(mms);
> > +}
> > +
> > +/** Close the MMSH/MMST connection */
> > +static int mms_close(URLContext *h)
> > +{
> > + MMSContext *mms = (MMSContext *)h->priv_data;
> > +
> > + if(mms->mms_hd) {
> > + send_close_packet(mms);
> > + url_close(mms->mms_hd);
> > + }
> > +
> > + /* free all separately allocated pointers in mms */
> > + av_free(mms->asf_header);
> > + av_freep(&h->priv_data);
> > +
> > + return 0;
> > +}
> > +
> > +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
> > + ff_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_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;
> > + } else {
> > + if((mms->incoming_flags == 0X08) || (mms->incoming_flags ==
> 0X0C)) {
> > + 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;
>
> is this the same as:
>
> 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;
>
> iam asking because this looks simpler to me
>
>
> anyway, if baptiste wants then iam ok with this being commited and any
> remaining issues being corrected as we find them
> a test with some corrupted (like a fuzzer) packets would also be usefull
> i think at some point in the future
>
>
> fixed.
the new patch attached below.
zhentan
--
Best wishes~
-------------- next part --------------
A non-text attachment was scrubbed...
Name: mmst_15.patch
Type: application/octet-stream
Size: 27486 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20100525/d66c1642/attachment.obj>
More information about the ffmpeg-devel
mailing list