[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