[FFmpeg-devel] [patch]MMS protocol over TCP

Michael Niedermayer michaelni
Mon May 24 00:48:07 CEST 2010


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


> +        } 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


[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

I am the wisest man alive, for I know one thing, and that is that I know
nothing. -- Socrates
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20100524/361aa4de/attachment.pgp>



More information about the ffmpeg-devel mailing list