音频管道播放暂停时。有的时候不能暂停

mnjhuy86
Posts: 16
Joined: Fri Jun 05, 2020 8:10 am

音频管道播放暂停时。有的时候不能暂停

Postby mnjhuy86 » Mon Jul 20, 2020 2:31 am

使用音乐管道播放音乐是暂停有的时候会失败
log

Code: Select all

[0;32mI (5821) MUSIC: el_state:2[0m
[0;32mI (5821) MUSIC: [ * ] Pausing audio pipeline[0m//按暂停
[0;32mI (5841) MUSIC: Audio event 8 from file element[0m
[0;32mI (5841) MUSIC: AEL_STATUS_STATE_PAUSED[0m
[0;32mI (5841) AUDIO_ELEMENT: [file] AEL_MSG_CMD_PAUSE[0m
[0;32mI (5841) STAGEFRIGHTMP3_DECODER: Closed[0m
[0;32mI (5841) MUSIC: Audio event 8 from mp3 element[0m
[0;32mI (5851) MUSIC: AEL_STATUS_STATE_PAUSED[0m
[0;32mI (5851) AUDIO_ELEMENT: [mp3] AEL_MSG_CMD_PAUSE[0m
//这个时候后面应该会有[filter]的暂停命令。但这个命令丢失了

[0;32mI (9861) MUSIC: el_state:3[0m
[0;32mI (9861) MUSIC: [ * ] Resuming audio pipeline[0m//按恢复按键
[0;32mI (9861) AUDIO_ELEMENT: [mp3] AEL_MSG_CMD_RESUME,state:3[0m
[0;32mI (9861) STAGEFRIGHTMP3_DECODER: MP3 opened[0m
[0;32mI (9861) MUSIC: Audio event 9 from mp3 element[0m
[0;32mI (9871) MUSIC: Audio event 8 from raw element[0m
[0;32mI (9871) MUSIC: AEL_STATUS_STATE_RUNNING[0m
[0;32mI (9881) MUSIC: Audio event 8 from mp3 element[0m
[0;32mI (9881) MUSIC: AEL_STATUS_STATE_RUNNING[0m
[0;32mI (9901) MUSIC: Audio event 8 from filter element[0m
[0;32mI (9901) MUSIC: AEL_STATUS_STATE_PAUSED[0m
[0;32mI (9901) AUDIO_ELEMENT: [filter] AEL_MSG_CMD_PAUSE[0m //这个是之前的暂停命令。而在恢复中执行了,后面系统就乱了
[0;32mI (9901) AUDIO_ELEMENT: [file] AEL_MSG_CMD_RESUME,state:3[0m
[0;32mI (9911) FATFS_STREAM: File size is 1883189 byte,pos:94208[0m
[0;32mI (9921) MUSIC: Audio event 8 from file element[0m
[0;32mI (9921) MUSIC: AEL_STATUS_STATE_RUNNING[0m
暂停命令发送出来了。但等待命令执行不成功。暂停失败

Code: Select all

esp_err_t audio_element_pause(audio_element_handle_t el)
{
    if (!el->task_run) {
        ESP_LOGW(TAG, "[%s] Element has not create when AUDIO_ELEMENT_PAUSE", el->tag);
        return ESP_FAIL;
    }
    if ((el->state >= AEL_STATE_PAUSED)) {
        audio_element_force_set_state(el, AEL_STATE_PAUSED);
        ESP_LOGD(TAG, "[%s] Element already paused, state:%d", el->tag, el->state);
        return ESP_OK;
    }
    xEventGroupClearBits(el->state_event, PAUSED_BIT);
    if (el->task_stack <= 0) {
        el->is_running = false;
        audio_element_force_set_state(el, AEL_STATE_PAUSED);
        return ESP_OK;
    }
    if (audio_element_cmd_send(el, AEL_MSG_CMD_PAUSE) != ESP_OK) {
        ESP_LOGE(TAG, "[%s] Element send cmd error when AUDIO_ELEMENT_PAUSE", el->tag);
        return ESP_FAIL;
    }
    EventBits_t uxBits = xEventGroupWaitBits(el->state_event, PAUSED_BIT, false, true, DEFAULT_MAX_WAIT_TIME);
    esp_err_t ret = ESP_FAIL;
    if (uxBits & PAUSED_BIT) { //这个不成立。AEL_MSG_CMD_PAUSE命令发送了,
        ret = ESP_OK;
    }
    return ret;
}
这个任务一直卡在 if (audio_element_process_running(el) != ESP_OK)这里面读rb,
而不能执行 if (audio_event_iface_waiting_cmd_msg(el->iface_event) != ESP_OK) {//读取之前发送的暂停命令。暂停失败。
只有这下一个恢复命令把之前的音频元素运行了,之前的音频元素写入数据了了。当前音频元素读取数据后。再读cmd.而读取出来的是之前队列中已经存在的暂停命令。

Code: Select all

void audio_element_task(void *pv)
{
    audio_element_handle_t el = (audio_element_handle_t)pv;
    el->task_run = true;
    xEventGroupSetBits(el->state_event, TASK_CREATED_BIT);
    audio_element_force_set_state(el, AEL_STATE_INIT);
    audio_event_iface_set_cmd_waiting_timeout(el->iface_event, portMAX_DELAY);
    if (el->buf_size > 0) {
        el->buf = audio_malloc(el->buf_size);
        AUDIO_MEM_CHECK(TAG, el->buf, {
            el->task_run = false;
            ESP_LOGE(TAG, "[%s] Error malloc element buffer", el->tag);
        });
    }
    xEventGroupClearBits(el->state_event, STOPPED_BIT);
    while (el->task_run) {
        if (audio_event_iface_waiting_cmd_msg(el->iface_event) != ESP_OK) {//
            xEventGroupSetBits(el->state_event, STOPPED_BIT);
            break;
        }
        if (audio_element_process_running(el) != ESP_OK) { //之前的音频元素暂停了,ringbuffer里面没有数据时,当前音频过犹不及在中取不出数据。一前在等待取数据。不能去执行audio_event_iface_waiting_cmd_msg,不能执行暂停命令了
            // continue;。
        }
    }

    if (el->is_open && el->close) {
        ESP_LOGD(TAG, "[%s] el closed", el->tag);
        el->close(el);
        el->is_open = false;
    }
    audio_free(el->buf);
    ESP_LOGD(TAG, "[%s] el task deleted,%d", el->tag, uxTaskGetStackHighWaterMark(NULL));
    el->stopping = false;
    el->task_run = false;
    xEventGroupSetBits(el->state_event, TASK_DESTROYED_BIT);
    vTaskDelete(NULL);
}
if (audio_element_process_running(el) != ESP_OK)一直卡在读取数据中。

Code: Select all


int rb_read(ringbuf_handle_t rb, char *buf, int buf_len, TickType_t ticks_to_wait)
{
    int read_size = 0;
    int total_read_size = 0;
    int ret_val = 0;

    if (rb == NULL) {
        return RB_FAIL;
    }

    while (buf_len) {
        //take buffer lock
        if (rb_block(rb->lock, portMAX_DELAY) != pdTRUE) {
            ret_val = RB_TIMEOUT;
            goto read_err;
        }

        if (rb->fill_cnt < buf_len) {
            read_size = rb->fill_cnt;
            /**
             * When non-multiple of 4(word size) bytes are written to I2S, there is noise.
             * Below is the kind of workaround to read only in multiple of 4. Avoids noise when rb is read in small chunks.
             * Note that, when we have buf_len bytes available in rb, we still read those irrespective of if it's multiple of 4.
             */
            read_size = read_size & 0xfffffffc;
            if ((read_size == 0) && rb->is_done_write) {
                read_size = rb->fill_cnt;
            }
        } else {
            read_size = buf_len;
        }

        if (read_size == 0) { //一直卡在这个。因为之前的音频元素已经暂停了。一直等待也不能把数据读出来
            //no data to read, release thread block to allow other threads to write data
            rb_release(rb->lock);

            if (rb->is_done_write) {
                ret_val = RB_DONE;
                goto read_err;
            }
            if (rb->abort_read) {
                ret_val = RB_ABORT;
                goto read_err;
            }
            if (rb->unblock_reader_flag) {
                //reader_unblock is nothing but forced timeout
                ret_val = RB_TIMEOUT;
                goto read_err;
            }
            rb_release(rb->can_write);
            //wait till some data available to read
            if (rb_block(rb->can_read, ticks_to_wait) != pdTRUE) {
                ret_val = RB_TIMEOUT;
                goto read_err;
            }
            continue;
        }

        if ((rb->p_r + read_size) > (rb->p_o + rb->size)) {
            int rlen1 = rb->p_o + rb->size - rb->p_r;
            int rlen2 = read_size - rlen1;
            if (buf) {
                memcpy(buf, rb->p_r, rlen1);
                memcpy(buf + rlen1, rb->p_o, rlen2);
            }
            rb->p_r = rb->p_o + rlen2;
        } else {
            if (buf) {
                memcpy(buf, rb->p_r, read_size);
            }
            rb->p_r = rb->p_r + read_size;
        }

        buf_len -= read_size;
        rb->fill_cnt -= read_size;
        total_read_size += read_size;
        buf += read_size;
        rb_release(rb->lock);
        if (buf_len == 0) {
            break;
        }
    }
read_err:
    if (total_read_size > 0) {
        rb_release(rb->can_write);
    }
    if ((ret_val == RB_FAIL) ||
        (ret_val == RB_ABORT)) {
        total_read_size = ret_val;
    }
    rb->unblock_reader_flag = false; /* We are anyway unblocking the reader */
    return total_read_size > 0 ? total_read_size : ret_val;
}
以上是有个人见解不知道对不对。
但解决的方法一直没找到 。暂停老是音频元素暂停失败。
有大神能指导一下吗

Who is online

Users browsing this forum: No registered users and 3 guests