Error from HAL stream in function get_presentation_position operation is not permitted

   日期:2020-07-10     浏览:161    评论:0    
核心提示:此文来自一个小白首先根据log我们可以找到log的打印位置 hardware/interfaces/audiodefault/Stream.cpp其代码如下Result Stream::analyzeStatus(const char* funcName, int status, const std::vector& ignoreErrors) { if (status != 0 &&am

此文来自一个小白(Android 8.1)

首先根据log我们可以找到log的打印位置 hardware/interfaces/audiodefault/Stream.cpp
其代码如下

Result Stream::analyzeStatus(const char* funcName, int status,
                             const std::vector<int>& ignoreErrors) {
    if (status != 0 && (ignoreErrors.empty() || !element_in(-status, ignoreErrors))) {
        ALOGW("Error from HAL stream in function %s: %s", funcName, strerror(-status));
    }
    switch (status) {
        case 0: return Result::OK;
        case -EINVAL: return Result::INVALID_ARGUMENTS;
        case -ENODATA: return Result::INVALID_STATE;
        case -ENODEV: return Result::NOT_INITIALIZED;
        case -ENOSYS: return Result::NOT_SUPPORTED;
        default: return Result::INVALID_STATE;
    }
}

然后我们继续找,是谁调用了他 StreamOut.cpp

Result StreamOut::getPresentationPositionImpl(audio_stream_out_t* stream,
                                              uint64_t* frames,
                                              TimeSpec* timeStamp) {
    // Don't logspam on EINVAL--it's normal for get_presentation_position
    // to return it sometimes. EAGAIN may be returned by A2DP audio HAL
    // implementation. ENODATA can also be reported while the writer is
    // continuously querying it, but the stream has been stopped.
    static const std::vector<int> ignoredErrors{EINVAL, EAGAIN, ENODATA};
    Result retval(Result::NOT_SUPPORTED);
    if (stream->get_presentation_position == NULL) return retval;
    struct timespec halTimeStamp;
    retval = Stream::analyzeStatus("get_presentation_position",
                                   stream->get_presentation_position(stream, frames, &halTimeStamp),
                                   ignoredErrors);
    if (retval == Result::OK) {
        timeStamp->tvSec = halTimeStamp.tv_sec;
        timeStamp->tvNSec = halTimeStamp.tv_nsec;
    }
    return retval;
}

在 Stream::analyzeStatus 中传入的 status 便是stream->get_presentation_position(stream, frames, &halTimeStamp)
那 stream->get_presentation_position 这个方法又是在什么地方
继续寻找 你会发现在不同的时候这个方法指向的方法也不同,然额,触发这个log的方法也必然在其中
之后我们会在发现audio_hal.c中有这麽一句话out->stream.get_presentation_position = out_get_presentation_position;
(hardware/libhardware/modules/usbaudio/audio_hal.c)
那,这美滋滋 那之前到status就是 out_get_presentation_position 这个函数的返回值了 其后继续看函数

static int out_get_presentation_position(const struct audio_stream_out *stream,
                                         uint64_t *frames, struct timespec *timestamp)
{
    struct stream_out *out = (struct stream_out *)stream; // discard const qualifier
    stream_lock(&out->lock);

    const alsa_device_proxy *proxy = &out->proxy;
    const int ret = proxy_get_presentation_position(proxy, frames, timestamp);

    stream_unlock(&out->lock);
    return ret;
}

哦 原来是你 proxy_get_presentation_position 继续找
system/media/alsa_utils/alsa_device_proxy.c

int proxy_get_presentation_position(const alsa_device_proxy * proxy,
        uint64_t *frames, struct timespec *timestamp)
{
    int ret = -EPERM; // -1
    unsigned int avail;
    if (proxy->pcm != NULL
            && pcm_get_htimestamp(proxy->pcm, &avail, timestamp) == 0) {
        const size_t kernel_buffer_size =
                proxy->alsa_config.period_size * proxy->alsa_config.period_count;
        if (avail > kernel_buffer_size) {
            ALOGE("stream available frames(%u) > buffer size(%zu)", avail, kernel_buffer_size);
        } else {
            int64_t signed_frames = proxy->transferred - kernel_buffer_size + avail;
            // It is possible to compensate for additional driver and device delay
            // by changing signed_frames. Example:
            // signed_frames -= 20  * proxy->alsa_config.rate / 1000;
            if (signed_frames >= 0) {
                *frames = signed_frames;
                ret = 0;
            }
        }
    }
    return ret;
}

最终方法找到了 but 我是个小白,而身为大佬的你,一定可以 完美解决

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服