예제 #1
0
static int mms_open(URLContext *h, const char *uri, int flags)
{
    MMSTContext *mmst;
    MMSContext *mms;
    int port, err;
    char tcpname[256];

    h->is_streamed = 1;
    mmst = h->priv_data = av_mallocz(sizeof(MMSTContext));
    if (!h->priv_data)
        return AVERROR(ENOMEM);
    mms = &mmst->mms;

    // only for MMS over TCP, so set proto = NULL
    av_url_split(NULL, 0, NULL, 0,
                 mmst->host, sizeof(mmst->host), &port, mmst->path,
                 sizeof(mmst->path), uri);

    if(port < 0)
        port = 1755; // defaut mms protocol port

    // establish tcp connection.
    ff_url_join(tcpname, sizeof(tcpname), "tcp", NULL, mmst->host, port, NULL);
    err = ffurl_open(&mms->mms_hd, tcpname, AVIO_RDWR);
    if (err)
        goto fail;

    mmst->packet_id        = 3;          // default, initial value.
    mmst->header_packet_id = 2;          // default, initial value.
    err = mms_safe_send_recv(mmst, send_startup_packet, SC_PKT_CLIENT_ACCEPTED);
    if (err)
        goto fail;
    err = mms_safe_send_recv(mmst, send_time_test_data, SC_PKT_TIMING_TEST_REPLY);
    if (err)
        goto fail;
    err = mms_safe_send_recv(mmst, send_protocol_select, SC_PKT_PROTOCOL_ACCEPTED);
    if (err)
        goto fail;
    err = mms_safe_send_recv(mmst, send_media_file_request, SC_PKT_MEDIA_FILE_DETAILS);
    if (err)
        goto fail;
    err = mms_safe_send_recv(mmst, send_media_header_request, SC_PKT_HEADER_REQUEST_ACCEPTED);
    if (err)
        goto fail;
    err = mms_safe_send_recv(mmst, NULL, SC_PKT_ASF_HEADER);
    if (err)
        goto fail;
    if((mmst->incoming_flags != 0X08) && (mmst->incoming_flags != 0X0C))
    {
        av_log(NULL, AV_LOG_ERROR,
               "The server does not support MMST (try MMSH or RTSP)\n");
        err = AVERROR(EINVAL);
        goto fail;
    }
    err = ff_mms_asf_header_parser(mms);
    if (err)
    {
        av_dlog(NULL, "asf header parsed failed!\n");
        goto fail;
    }
    mms->header_parsed = 1;

    if (!mms->asf_packet_len || !mms->stream_num)
        goto fail;

    clear_stream_buffers(mms);
    err = mms_safe_send_recv(mmst, send_stream_selection_request, SC_PKT_STREAM_ID_ACCEPTED);
    if (err)
        goto fail;
    // send media packet request
    err = mms_safe_send_recv(mmst, send_media_packet_request, SC_PKT_MEDIA_PKT_FOLLOWS);
    if (err)
    {
        goto fail;
    }
    av_dlog(NULL, "Leaving open (success)\n");
    return 0;
fail:
    mms_close(h);
    av_dlog(NULL, "Leaving open (failure: %d)\n", err);
    return err;
}
예제 #2
0
파일: mmsh.c 프로젝트: AndyA/ffmbc
static int get_http_header_data(MMSHContext *mmsh)
{
    MMSContext *mms = &mmsh->mms;
    int res, len;
    ChunkType chunk_type;

    for (;;) {
        len = 0;
        res = chunk_type = get_chunk_header(mmsh, &len);
        if (res < 0) {
            return res;
        } else if (chunk_type == CHUNK_TYPE_ASF_HEADER){
            // get asf header and stored it
            if (!mms->header_parsed) {
                if (mms->asf_header) {
                    if (len != mms->asf_header_size) {
                        mms->asf_header_size = len;
                        av_dlog(NULL, "Header len changed from %d to %d\n",
                                mms->asf_header_size, len);
                        av_freep(&mms->asf_header);
                    }
                }
                mms->asf_header = av_mallocz(len);
                if (!mms->asf_header) {
                    return AVERROR(ENOMEM);
                }
                mms->asf_header_size = len;
            }
            if (len > mms->asf_header_size) {
                av_log(NULL, AV_LOG_ERROR,
                       "Asf header packet len = %d exceed the asf header buf size %d\n",
                       len, mms->asf_header_size);
                return AVERROR(EIO);
            }
            res = url_read_complete(mms->mms_hd, mms->asf_header, len);
            if (res != len) {
                av_log(NULL, AV_LOG_ERROR,
                       "Recv asf header data len %d != expected len %d\n", res, len);
                return AVERROR(EIO);
            }
            mms->asf_header_size = len;
            if (!mms->header_parsed) {
                res = ff_mms_asf_header_parser(mms);
                mms->header_parsed = 1;
                return res;
            }
        } else if (chunk_type == CHUNK_TYPE_DATA) {
            // read data packet and do padding
            return read_data_packet(mmsh, len);
        } else {
            if (len) {
                if (len > sizeof(mms->in_buffer)) {
                    av_log(NULL, AV_LOG_ERROR,
                           "Other packet len = %d exceed the in_buffer size %zu\n",
                           len, sizeof(mms->in_buffer));
                    return AVERROR(EIO);
                }
                res = url_read_complete(mms->mms_hd, mms->in_buffer, len);
                if (res != len) {
                    av_log(NULL, AV_LOG_ERROR, "Read other chunk type data failed!\n");
                    return AVERROR(EIO);
                } else {
                    av_dlog(NULL, "Skip chunk type %d \n", chunk_type);
                    continue;
                }
            }
        }
    }
    return 0;
}