コード例 #1
0
static int64_t cache_seek(URLContext *h, int64_t pos, int whence)
{
    Context *c= (Context *)h->priv_data;

    if (whence == AVSEEK_SIZE) {
        pos= ffurl_seek(c->inner, pos, whence);
        if(pos <= 0){
            pos= ffurl_seek(c->inner, -1, SEEK_END);
            ffurl_seek(c->inner, c->end, SEEK_SET);
            if(pos <= 0)
                return c->end;
        }
        return pos;
    }

    pos= lseek(c->fd, pos, whence);
    if(pos<0){
        return pos;
    }else if(pos <= c->end){
        c->pos= pos;
        return pos;
    }else{
        lseek(c->fd, c->pos, SEEK_SET);
        return AVERROR(EPIPE);
    }
}
コード例 #2
0
ファイル: concat.c プロジェクト: DaveDaCoda/mythtv
static int64_t concat_seek(URLContext *h, int64_t pos, int whence)
{
    int64_t result;
    struct concat_data  *data  = h->priv_data;
    struct concat_nodes *nodes = data->nodes;
    size_t i;

    switch (whence) {
    case SEEK_END:
        for (i = data->length - 1; i && pos < -nodes[i].size; i--)
            pos += nodes[i].size;
        break;
    case SEEK_CUR:
        /* get the absolute position */
        for (i = 0; i != data->current; i++)
            pos += nodes[i].size;
        pos += ffurl_seek(nodes[i].uc, 0, SEEK_CUR);
        whence = SEEK_SET;
        /* fall through with the absolute position */
    case SEEK_SET:
        for (i = 0; i != data->length - 1 && pos >= nodes[i].size; i++)
            pos -= nodes[i].size;
        break;
    default:
        return AVERROR(EINVAL);
    }

    result = ffurl_seek(nodes[i].uc, pos, whence);
    if (result >= 0) {
        data->current = i;
        while (i)
            result += nodes[--i].size;
    }
    return result;
}
コード例 #3
0
ファイル: avio.c プロジェクト: andoma/libav
int64_t ffurl_size(URLContext *h)
{
    int64_t pos, size;

    size= ffurl_seek(h, 0, AVSEEK_SIZE);
    if(size<0){
        pos = ffurl_seek(h, 0, SEEK_CUR);
        if ((size = ffurl_seek(h, -1, SEEK_END)) < 0)
            return size;
        size++;
        ffurl_seek(h, pos, SEEK_SET);
    }
    return size;
}
コード例 #4
0
int64_t AVFRingBuffer::AVF_Seek_Packet(void *opaque, int64_t offset, int whence)
{
    if (!opaque)
        return 0;

    return ffurl_seek((URLContext *)opaque, offset, whence);
}
コード例 #5
0
static int64_t cache_seek(URLContext *h, int64_t pos, int whence)
{
    Context *c= (Context*)h->priv_data;

    int64_t ret;

    if(AVSEEK_SIZE != whence){
    	av_log(h, AV_LOG_ERROR, "c->inner->filename:%s,ucache seek!!!:pos=%lld,c->pos=%lld,whence=%d\n",c->inner->filename,pos,c->pos,whence);
    }
    ret = ffurl_seek(c->inner, pos, whence);

    if( ret >=0 ) {

    	if(AVSEEK_SIZE != whence){
    		av_log(h, AV_LOG_ERROR, "ffurl_seek = %lld\n",ret);
    		pos= lseek(c->fd, pos, whence);
    		if(pos != ret){
    			av_log(h, AV_LOG_ERROR, "lseek pos != ret pos=%lld",pos);
    		}else{
    			c->pos = ret;
    		}
    	}
    }

    return ret;

}
コード例 #6
0
static int cache_read(URLContext *h, unsigned char *buf, int size)
{
    	Context *c= (Context*)h->priv_data;

    	int r = 0;

    	//av_log(h, AV_LOG_INFO, "cache_read enter\n",r);
        r = ffurl_read(c->inner, buf, size);
        if( r > 0 && c->fd >= 0 ){
        	int64_t size;
        	//av_log(h, AV_LOG_INFO, "cache_read = %d bytes\n",r);
            int r2= write(c->fd, buf, r);
            av_assert0(r2==r); // FIXME handle cache failure
            c->pos += r;
            c->end += r;

            //判断是否缓存完毕
            size = ffurl_seek(c->inner, 0, AVSEEK_SIZE);

            if( size == c->pos && c->end >= size ){
    		    if(c->local_buffer_path)notifyCacheEnd(h,1);
    			av_log(h, AV_LOG_INFO, "ucache: ok1\n");
    			close(c->fd);
    			c->fd = -1;
            }

        }else{
        	if(c->fd >=0)av_log(h, AV_LOG_ERROR, "cache_read:ffurl_read failed\n",r);
        }
        return r;

}
コード例 #7
0
static int cache_close(URLContext *h)
{
	int64_t size;

    Context *c= (Context*)h->priv_data;

    if(c->fd >= 0)close(c->fd);

    //判断是否需要保存
    if(c->local_buffer_path && c->fd >= 0){
		size = ffurl_seek(c->inner, 0, AVSEEK_SIZE);

		if( size != c->pos || c->end < size ){
			//删除文件
			unlink(c->local_buffer_path);
			av_log(h, AV_LOG_INFO, "ucache: failed size=%lld,c->pos=%lld,c->end=%lld\n",size,c->pos,c->end);
		    //通知上层缓存失败
		    if(c->local_buffer_path)notifyCacheEnd(h,0);
		}else{
		    //通知上层缓存成功
		    if(c->local_buffer_path)notifyCacheEnd(h,1);
			av_log(h, AV_LOG_INFO, "ucache: ok2\n");
		}
    }

    ffurl_close(c->inner);

    return 0;
}
コード例 #8
0
int ffurl_connect(URLContext *uc, AVDictionary **options)
{
    int err;
    AVDictionary *tmp_opts = NULL;
    AVDictionaryEntry *e;

    if (!options)
        options = &tmp_opts;

    // Check that URLContext was initialized correctly and lists are matching if set
    av_assert0(!(e=av_dict_get(*options, "protocol_whitelist", NULL, 0)) ||
               (uc->protocol_whitelist && !strcmp(uc->protocol_whitelist, e->value)));
    av_assert0(!(e=av_dict_get(*options, "protocol_blacklist", NULL, 0)) ||
               (uc->protocol_blacklist && !strcmp(uc->protocol_blacklist, e->value)));

    if (uc->protocol_whitelist && av_match_list(uc->prot->name, uc->protocol_whitelist, ',') <= 0) {
        av_log(uc, AV_LOG_ERROR, "Protocol not on whitelist \'%s\'!\n", uc->protocol_whitelist);
        return AVERROR(EINVAL);
    }

    if (uc->protocol_blacklist && av_match_list(uc->prot->name, uc->protocol_blacklist, ',') > 0) {
        av_log(uc, AV_LOG_ERROR, "Protocol blacklisted \'%s\'!\n", uc->protocol_blacklist);
        return AVERROR(EINVAL);
    }

    if (!uc->protocol_whitelist && uc->prot->default_whitelist) {
        av_log(uc, AV_LOG_DEBUG, "Setting default whitelist '%s'\n", uc->prot->default_whitelist);
        uc->protocol_whitelist = av_strdup(uc->prot->default_whitelist);
        if (!uc->protocol_whitelist) {
            return AVERROR(ENOMEM);
        }
    } else if (!uc->protocol_whitelist)
        av_log(uc, AV_LOG_DEBUG, "No default whitelist set\n"); // This should be an error once all declare a default whitelist

    if ((err = av_dict_set(options, "protocol_whitelist", uc->protocol_whitelist, 0)) < 0)
        return err;
    if ((err = av_dict_set(options, "protocol_blacklist", uc->protocol_blacklist, 0)) < 0)
        return err;

    err =
        uc->prot->url_open2 ? uc->prot->url_open2(uc,
                                                  uc->filename,
                                                  uc->flags,
                                                  options) :
        uc->prot->url_open(uc, uc->filename, uc->flags);

    av_dict_set(options, "protocol_whitelist", NULL, 0);
    av_dict_set(options, "protocol_blacklist", NULL, 0);

    if (err)
        return err;
    uc->is_connected = 1;
    /* We must be careful here as ffurl_seek() could be slow,
     * for example for http */
    if ((uc->flags & AVIO_FLAG_WRITE) || !strcmp(uc->prot->name, "file"))
        if (!uc->is_streamed && ffurl_seek(uc, 0, SEEK_SET) < 0)
            uc->is_streamed = 1;
    return 0;
}
コード例 #9
0
ファイル: avio.c プロジェクト: andoma/libav
int ffurl_connect(URLContext* uc)
{
    int err = uc->prot->url_open(uc, uc->filename, uc->flags);
    if (err)
        return err;
    uc->is_connected = 1;
    //We must be careful here as ffurl_seek() could be slow, for example for http
    if(   (uc->flags & AVIO_FLAG_WRITE)
       || !strcmp(uc->prot->name, "file"))
        if(!uc->is_streamed && ffurl_seek(uc, 0, SEEK_SET) < 0)
            uc->is_streamed= 1;
    return 0;
}
コード例 #10
0
ファイル: subfile.c プロジェクト: DeHackEd/FFmpeg
static int slave_seek(URLContext *h)
{
    SubfileContext *c = h->priv_data;
    int64_t ret;

    if ((ret = ffurl_seek(c->h, c->pos, SEEK_SET)) != c->pos) {
        if (ret >= 0)
            ret = AVERROR_BUG;
        av_log(h, AV_LOG_ERROR, "Impossible to seek in file: %s\n",
               av_err2str(ret));
        return ret;
    }
    return 0;
}
コード例 #11
0
long long StreamingRingBuffer::Seek(long long pos, int whence, bool has_lock)
{
    if (!m_context)
        return 0;

    poslock.lockForWrite();
    int seek = ffurl_seek(m_context, pos, whence);
    poslock.unlock();

    if (seek < 0)
    {
        ateof = true;
        return 0;
    }
    return pos;
}
コード例 #12
0
bool StreamingRingBuffer::OpenFile(const QString &lfilename, uint retry_ms)
{
    avcodeclock->lock();
    av_register_all();
    avcodeclock->unlock();
    RingBuffer::AVFormatInitNetwork();

    rwlock.lockForWrite();

    safefilename = lfilename;
    filename = lfilename;

    // TODO check whether local area file

    QUrl url = filename;
    if (url.path().endsWith(QLatin1String("m3u8"), Qt::CaseInsensitive))
    {
        url.setScheme("hls+http");
    }

    int res = ffurl_open(&m_context, url.toString().toLatin1(), AVIO_FLAG_READ,
                         NULL, NULL);
    if (res >=0 && m_context &&
        !m_context->is_streamed && ffurl_seek(m_context, 0, SEEK_SET) >= 0)
    {
        m_streamed   = false;
        m_allowSeeks = true;
    }

    LOG(VB_GENERAL, LOG_INFO, LOC + QString("Trying %1 (allow seeks: %2")
        .arg(filename).arg(m_allowSeeks));

    rwlock.unlock();

    if (res < 0 || !m_context)
    {
        LOG(VB_GENERAL, LOG_ERR, LOC +
            QString("Failed to open stream (error %1)") .arg(res));
        return false;
    }

    return true;
}
コード例 #13
0
ファイル: concat.c プロジェクト: Acidburn0zzz/libav
static int concat_read(URLContext *h, unsigned char *buf, int size)
{
    int result, total = 0;
    struct concat_data  *data  = h->priv_data;
    struct concat_nodes *nodes = data->nodes;
    size_t i = data->current;

    while (size > 0) {
        result = ffurl_read(nodes[i].uc, buf, size);
        if (result < 0)
            return total ? total : result;
        if (!result)
            if (i + 1 == data->length ||
                ffurl_seek(nodes[++i].uc, 0, SEEK_SET) < 0)
                break;
        total += result;
        buf   += result;
        size  -= result;
    }
    data->current = i;
    return total;
}
コード例 #14
0
static int64_t CacheHttp_ffurl_seek(URLContext *h, int64_t pos, int whence)
{
    return ffurl_seek(h, pos, whence);
}
コード例 #15
0
ファイル: avio.c プロジェクト: andoma/libav
int64_t url_seek(URLContext *h, int64_t pos, int whence)
{
    return ffurl_seek(h, pos, whence);
}
コード例 #16
0
ファイル: crypto.c プロジェクト: coffeez/FFmpeg
static int64_t crypto_seek(URLContext *h, int64_t pos, int whence)
{
    CryptoContext *c = h->priv_data;
    int64_t block;
    int64_t newpos;

    if (c->flags & AVIO_FLAG_WRITE) {
        av_log(h, AV_LOG_ERROR,
            "Crypto: seek not supported for write\r\n");
        /* seems the most appropriate error to return */
        return AVERROR(ESPIPE);
    }

    // reset eof, else we won't read it correctly if we already hit eof.
    c->eof = 0;

    switch (whence) {
    case SEEK_SET:
        break;
    case SEEK_CUR:
        pos = pos + c->position;
        break;
    case SEEK_END: {
        int64_t newpos = ffurl_seek( c->hd, pos, AVSEEK_SIZE );
        if (newpos < 0) {
            av_log(h, AV_LOG_ERROR,
                "Crypto: seek_end - can't get file size (pos=%lld)\r\n", (long long int)pos);
            return newpos;
        }
        pos = newpos - pos;
        }
        break;
    case AVSEEK_SIZE: {
        int64_t newpos = ffurl_seek( c->hd, pos, AVSEEK_SIZE );
        return newpos;
        }
        break;
    default:
        av_log(h, AV_LOG_ERROR,
            "Crypto: no support for seek where 'whence' is %d\r\n", whence);
        return AVERROR(EINVAL);
    }

    c->outdata = 0;
    c->indata = 0;
    c->indata_used = 0;
    c->outptr = c->outbuffer;

    // identify the block containing the IV for the
    // next block we will decrypt
    block = pos/BLOCKSIZE;
    if (block == 0) {
        // restore the iv to the seed one - this is the iv for the FIRST block
        memcpy( c->decrypt_iv, c->iv, c->ivlen );
        c->position = 0;
    } else {
        // else, go back one block - we will get av_cyrpt to read this block
        // which it will then store use as the iv.
        // note that the DECRYPTED result will not be correct,
        // but will be discarded
        block--;
        c->position = (block * BLOCKSIZE);
    }

    newpos = ffurl_seek( c->hd, c->position, SEEK_SET );
    if (newpos < 0) {
        av_log(h, AV_LOG_ERROR,
            "Crypto: nested protocol no support for seek or seek failed\n");
        return newpos;
    }

    // read and discard from here up to required position
    // (which will set the iv correctly to it).
    if (pos - c->position) {
        uint8_t buff[BLOCKSIZE*2]; // maximum size of pos-c->position
        int len = pos - c->position;
        int res;

        while (len > 0) {
            // note: this may not return all the bytes first time
            res = crypto_read(h, buff, len);
            if (res < 0)
                break;
            len -= res;
        }

        // if we did not get all the bytes
        if (len != 0) {
            char errbuf[100] = "unknown error";
            av_strerror(res, errbuf, sizeof(errbuf));
            av_log(h, AV_LOG_ERROR,
                "Crypto: discard read did not get all the bytes (%d remain) - read returned (%d)-%s\n",
                len, res, errbuf);
            return AVERROR(EINVAL);
        }
    }

    return c->position;
}