Android 8.1.0 Release 45 (OPM4.171019.021.Z1)

-----BEGIN PGP SIGNATURE-----
 
 iF0EABECAB0WIQRDQNE1cO+UXoOBCWTorT+BmrEOeAUCW4BXbgAKCRDorT+BmrEO
 eEY4AKCBM0DLJhFwSRwaQ/ajJmBee3jf/ACfS0OtZ9RSrqZ4Mqd0W51AQg+zoo4=
 =+spW
 -----END PGP SIGNATURE-----

Merge tag 'android-8.1.0_r45' into flo-aosp-o

Android 8.1.0 Release 45 (OPM4.171019.021.Z1)
This commit is contained in:
followmsi 2018-09-07 10:32:42 +02:00
commit b7a57aa2c4
6 changed files with 84 additions and 22 deletions

View File

@ -1,5 +1,5 @@
/*--------------------------------------------------------------------------
Copyright (c) 2010 - 2014, The Linux Foundation. All rights reserved.
Copyright (c) 2010 - 2014, 2018, The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@ -1095,7 +1095,7 @@ class omx_vdec: public qc_omx_component
}
static OMX_ERRORTYPE describeColorFormat(OMX_PTR params);
bool m_buffer_error;
};
#ifdef _MSM8974_

View File

@ -1,5 +1,5 @@
/*--------------------------------------------------------------------------
Copyright (c) 2010 - 2016, The Linux Foundation. All rights reserved.
Copyright (c) 2010 - 2016, 2018, The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
@ -596,7 +596,8 @@ omx_vdec::omx_vdec(): m_error_propogated(false),
client_set_fps(false),
m_last_rendered_TS(-1),
m_queued_codec_config_count(0),
secure_scaling_to_non_secure_opb(false)
secure_scaling_to_non_secure_opb(false),
m_buffer_error(false)
{
/* Assumption is that , to begin with , we have all the frames with decoder */
DEBUG_PRINT_HIGH("In %u bit OMX vdec Constructor", (unsigned int)sizeof(long) * 8);
@ -4732,6 +4733,7 @@ OMX_ERRORTYPE omx_vdec::use_output_buffer(
eRet = allocate_output_headers();
if (eRet == OMX_ErrorNone)
eRet = allocate_extradata();
output_use_buffer = true;
}
if (eRet == OMX_ErrorNone) {
@ -5147,7 +5149,6 @@ OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
index = bufferHdr - m_inp_mem_ptr;
DEBUG_PRINT_LOW("Free Input Buffer index = %d",index);
auto_lock l(buf_lock);
bufferHdr->pInputPortPrivate = NULL;
if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer) {
@ -5348,11 +5349,13 @@ OMX_ERRORTYPE omx_vdec::allocate_input_buffer(
unsigned i = 0;
unsigned char *buf_addr = NULL;
int pmem_fd = -1;
unsigned int align_size = 0;
(void) hComp;
(void) port;
if (bytes != drv_ctx.ip_buf.buffer_size) {
DEBUG_PRINT_LOW("Requested Size is wrong %u epected is %u",
(unsigned int)bytes, (unsigned int)drv_ctx.ip_buf.buffer_size);
@ -5407,8 +5410,10 @@ OMX_ERRORTYPE omx_vdec::allocate_input_buffer(
int rc;
DEBUG_PRINT_LOW("Allocate input Buffer");
#ifdef USE_ION
align_size = drv_ctx.ip_buf.buffer_size + 512;
align_size = (align_size + drv_ctx.ip_buf.alignment - 1)&(~(drv_ctx.ip_buf.alignment - 1));
drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment,
align_size, drv_ctx.op_buf.alignment,
&drv_ctx.ip_buf_ion_info[i].ion_alloc_data,
&drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE
#ifndef DISABLE_INPUT_BUFFER_CACHE
@ -5907,6 +5912,10 @@ OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hC
eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
}
} else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
if (output_use_buffer) {
DEBUG_PRINT_ERROR("Allocate output buffer not allowed after use buffer");
return OMX_ErrorBadParameter;
}
eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port,
appData,bytes);
} else {
@ -5967,6 +5976,7 @@ OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
(void) hComp;
DEBUG_PRINT_LOW("In for decoder free_buffer");
auto_lock l(buf_lock);
if (m_state == OMX_StateIdle &&
(BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
DEBUG_PRINT_LOW(" free buffer while Component in Loading pending");
@ -5983,7 +5993,7 @@ OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
post_event(OMX_EventError,
OMX_ErrorPortUnpopulated,
OMX_COMPONENT_GENERATE_EVENT);
m_buffer_error = true;
return OMX_ErrorIncorrectStateOperation;
} else if (m_state != OMX_StateInvalid) {
DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers");
@ -5991,7 +6001,6 @@ OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
OMX_ErrorPortUnpopulated,
OMX_COMPONENT_GENERATE_EVENT);
}
if (port == OMX_CORE_INPUT_PORT_INDEX) {
/*Check if arbitrary bytes*/
if (!arbitrary_bytes && !input_use_buffer)
@ -6088,6 +6097,7 @@ OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
post_event(OMX_CommandStateSet, OMX_StateLoaded,
OMX_COMPONENT_GENERATE_EVENT);
m_buffer_error = false;
}
}
return eRet;
@ -6261,6 +6271,11 @@ OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,
if (!temp_buffer || (temp_buffer - drv_ctx.ptr_inputbuffer) > (int)drv_ctx.ip_buf.actualcount) {
return OMX_ErrorBadParameter;
}
if (BITMASK_ABSENT(&m_inp_bm_count, nPortIndex) || m_buffer_error) {
DEBUG_PRINT_ERROR("ETBProxy: ERROR: invalid buffer, nPortIndex %u", nPortIndex);
return OMX_ErrorBadParameter;
}
/* If its first frame, H264 codec and reject is true, then parse the nal
and get the profile. Based on this, reject the clip playback */
if (first_frame == 0 && codec_type_parse == CODEC_TYPE_H264 &&
@ -6550,6 +6565,7 @@ OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy(
struct vdec_bufferpayload *ptr_outputbuffer = NULL;
struct vdec_output_frameinfo *ptr_respbuffer = NULL;
auto_lock l(buf_lock);
nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
if (!bufferAdd || !bufferAdd->pBuffer || nPortIndex >= drv_ctx.op_buf.actualcount) {
@ -6558,6 +6574,10 @@ OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy(
return OMX_ErrorBadParameter;
}
if (BITMASK_ABSENT(&m_out_bm_count, nPortIndex) || m_buffer_error) {
DEBUG_PRINT_ERROR("FTBProxy: ERROR: invalid buffer, nPortIndex %u", nPortIndex);
return OMX_ErrorBadParameter;
}
DEBUG_PRINT_LOW("FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
bufferAdd, bufferAdd->pBuffer);
/*Return back the output buffer to client*/
@ -7743,7 +7763,7 @@ int omx_vdec::async_message_process (void *context, void* message)
output_respbuf->pic_type = PICTURE_TYPE_B;
}
if (omx->output_use_buffer)
if (!omx->m_enable_android_native_buffers && omx->output_use_buffer)
memcpy ( omxhdr->pBuffer, (void *)
((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr +
(unsigned long)vdec_msg->msgdata.output_frame.offset),

View File

@ -1,5 +1,5 @@
/*--------------------------------------------------------------------------
Copyright (c) 2010 - 2016, The Linux Foundation. All rights reserved.
Copyright (c) 2010 - 2016, 2018, The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@ -1189,6 +1189,7 @@ class omx_vdec: public qc_omx_component
// list of extensions is not mutable after initialization
const VendorExtensionStore mVendorExtensionStore;
bool m_buffer_error;
};
#ifdef _MSM8974_

View File

@ -1,5 +1,5 @@
/*--------------------------------------------------------------------------
Copyright (c) 2010 - 2016, The Linux Foundation. All rights reserved.
Copyright (c) 2010 - 2016, 2018, The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
@ -648,7 +648,8 @@ omx_vdec::omx_vdec(): m_error_propogated(false),
m_queued_codec_config_count(0),
current_perf_level(V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL),
secure_scaling_to_non_secure_opb(false),
m_force_compressed_for_dpb(false)
m_force_compressed_for_dpb(false),
m_buffer_error(false)
{
m_pipe_in = -1;
m_pipe_out = -1;
@ -5572,6 +5573,7 @@ OMX_ERRORTYPE omx_vdec::use_output_buffer(
eRet = allocate_output_headers();
if (eRet == OMX_ErrorNone)
eRet = allocate_extradata();
output_use_buffer = true;
}
if (eRet == OMX_ErrorNone) {
@ -5994,7 +5996,6 @@ OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
index = bufferHdr - m_inp_mem_ptr;
DEBUG_PRINT_LOW("Free Input Buffer index = %d",index);
auto_lock l(buf_lock);
bufferHdr->pInputPortPrivate = NULL;
if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer) {
@ -6203,6 +6204,7 @@ OMX_ERRORTYPE omx_vdec::allocate_input_buffer(
unsigned i = 0;
unsigned char *buf_addr = NULL;
int pmem_fd = -1;
unsigned int align_size = 0;
(void) hComp;
(void) port;
@ -6262,8 +6264,10 @@ OMX_ERRORTYPE omx_vdec::allocate_input_buffer(
int rc;
DEBUG_PRINT_LOW("Allocate input Buffer");
#ifdef USE_ION
align_size = drv_ctx.ip_buf.buffer_size + 512;
align_size = (align_size + drv_ctx.ip_buf.alignment - 1)&(~(drv_ctx.ip_buf.alignment - 1));
drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment,
align_size, drv_ctx.op_buf.alignment,
&drv_ctx.ip_buf_ion_info[i].ion_alloc_data,
&drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ?
SECURE_FLAGS_INPUT_BUFFER : ION_FLAG_CACHED);
@ -6751,6 +6755,10 @@ OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hC
eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
}
} else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
if (output_use_buffer) {
DEBUG_PRINT_ERROR("Allocate output buffer not allowed after use buffer");
return OMX_ErrorBadParameter;
}
eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port,
appData,bytes);
} else {
@ -6811,6 +6819,7 @@ OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
(void) hComp;
DEBUG_PRINT_LOW("In for decoder free_buffer");
auto_lock l(buf_lock);
if (m_state == OMX_StateIdle &&
(BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
DEBUG_PRINT_LOW(" free buffer while Component in Loading pending");
@ -6827,7 +6836,7 @@ OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
post_event(OMX_EventError,
OMX_ErrorPortUnpopulated,
OMX_COMPONENT_GENERATE_EVENT);
m_buffer_error = true;
return OMX_ErrorIncorrectStateOperation;
} else if (m_state != OMX_StateInvalid) {
DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers");
@ -6932,6 +6941,7 @@ OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
post_event(OMX_CommandStateSet, OMX_StateLoaded,
OMX_COMPONENT_GENERATE_EVENT);
m_buffer_error = false;
}
}
return eRet;
@ -7101,6 +7111,11 @@ OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,
if (!temp_buffer || (temp_buffer - drv_ctx.ptr_inputbuffer) > (int)drv_ctx.ip_buf.actualcount) {
return OMX_ErrorBadParameter;
}
if (BITMASK_ABSENT(&m_inp_bm_count, nPortIndex) || m_buffer_error) {
DEBUG_PRINT_ERROR("ETBProxy: ERROR: invalid buffer, nPortIndex %u", nPortIndex);
return OMX_ErrorBadParameter;
}
/* If its first frame, H264 codec and reject is true, then parse the nal
and get the profile. Based on this, reject the clip playback */
if (first_frame == 0 && codec_type_parse == CODEC_TYPE_H264 &&
@ -7390,6 +7405,7 @@ OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy(
struct vdec_bufferpayload *ptr_outputbuffer = NULL;
struct vdec_output_frameinfo *ptr_respbuffer = NULL;
auto_lock l(buf_lock);
nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
if (bufferAdd == NULL || nPortIndex >= drv_ctx.op_buf.actualcount) {
@ -7398,6 +7414,10 @@ OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy(
return OMX_ErrorBadParameter;
}
if (BITMASK_ABSENT(&m_out_bm_count, nPortIndex) || m_buffer_error) {
DEBUG_PRINT_ERROR("FTBProxy: ERROR: invalid buffer, nPortIndex %u", nPortIndex);
return OMX_ErrorBadParameter;
}
DEBUG_PRINT_LOW("FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
bufferAdd, bufferAdd->pBuffer);
/*Return back the output buffer to client*/
@ -8671,7 +8691,7 @@ int omx_vdec::async_message_process (void *context, void* message)
if (omxhdr && omxhdr->nFilledLen) {
omx->request_perf_level(VIDC_NOMINAL);
}
if (omx->output_use_buffer && omxhdr->pBuffer &&
if (!omx->m_enable_android_native_buffers && omx->output_use_buffer && omxhdr->pBuffer &&
vdec_msg->msgdata.output_frame.bufferaddr)
memcpy ( omxhdr->pBuffer, (void *)
((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr +

View File

@ -1,5 +1,5 @@
/*--------------------------------------------------------------------------
Copyright (c) 2010 - 2017, The Linux Foundation. All rights reserved.
Copyright (c) 2010 - 2018, The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@ -1286,6 +1286,7 @@ class omx_vdec: public qc_omx_component
// list of extensions is not mutable after initialization
const VendorExtensionStore mVendorExtensionStore;
bool m_buffer_error;
};
#ifdef _MSM8974_

View File

@ -667,7 +667,8 @@ omx_vdec::omx_vdec(): m_error_propogated(false),
current_perf_level(V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL),
secure_scaling_to_non_secure_opb(false),
m_force_compressed_for_dpb(true),
m_is_display_session(false)
m_is_display_session(false),
m_buffer_error(false)
{
m_pipe_in = -1;
m_pipe_out = -1;
@ -5995,6 +5996,7 @@ OMX_ERRORTYPE omx_vdec::use_output_buffer(
eRet = allocate_output_headers();
if (eRet == OMX_ErrorNone)
eRet = allocate_extradata();
output_use_buffer = true;
}
if (eRet == OMX_ErrorNone) {
@ -6504,7 +6506,6 @@ OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
index = bufferHdr - m_inp_mem_ptr;
DEBUG_PRINT_LOW("Free Input Buffer index = %d",index);
auto_lock l(buf_lock);
bufferHdr->pInputPortPrivate = NULL;
if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer) {
@ -6730,6 +6731,7 @@ OMX_ERRORTYPE omx_vdec::allocate_input_buffer(
unsigned i = 0;
unsigned char *buf_addr = NULL;
int pmem_fd = -1;
unsigned int align_size = 0;
(void) hComp;
(void) port;
@ -6789,8 +6791,10 @@ OMX_ERRORTYPE omx_vdec::allocate_input_buffer(
int rc;
DEBUG_PRINT_LOW("Allocate input Buffer");
#ifdef USE_ION
align_size = drv_ctx.ip_buf.buffer_size + 512;
align_size = (align_size + drv_ctx.ip_buf.alignment - 1)&(~(drv_ctx.ip_buf.alignment - 1));
drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment,
align_size, drv_ctx.op_buf.alignment,
&drv_ctx.ip_buf_ion_info[i].ion_alloc_data,
&drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ?
SECURE_FLAGS_INPUT_BUFFER : 0);
@ -7346,6 +7350,10 @@ OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hC
eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
}
} else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
if (output_use_buffer) {
DEBUG_PRINT_ERROR("Allocate output buffer not allowed after use buffer");
return OMX_ErrorBadParameter;
}
eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port,
appData,bytes);
} else {
@ -7406,6 +7414,7 @@ OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
(void) hComp;
DEBUG_PRINT_LOW("In for decoder free_buffer");
auto_lock l(buf_lock);
if (m_state == OMX_StateIdle &&
(BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
DEBUG_PRINT_LOW(" free buffer while Component in Loading pending");
@ -7422,7 +7431,7 @@ OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
post_event(OMX_EventError,
OMX_ErrorPortUnpopulated,
OMX_COMPONENT_GENERATE_EVENT);
m_buffer_error = true;
return OMX_ErrorIncorrectStateOperation;
} else if (m_state != OMX_StateInvalid) {
DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers");
@ -7543,6 +7552,7 @@ OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
post_event(OMX_CommandStateSet, OMX_StateLoaded,
OMX_COMPONENT_GENERATE_EVENT);
m_buffer_error = false;
}
}
return eRet;
@ -7714,6 +7724,11 @@ OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,
if (!temp_buffer || (temp_buffer - drv_ctx.ptr_inputbuffer) > (int)drv_ctx.ip_buf.actualcount) {
return OMX_ErrorBadParameter;
}
if (BITMASK_ABSENT(&m_inp_bm_count, nPortIndex) || m_buffer_error) {
DEBUG_PRINT_ERROR("ETBProxy: ERROR: invalid buffer, nPortIndex %u", nPortIndex);
return OMX_ErrorBadParameter;
}
/* If its first frame, H264 codec and reject is true, then parse the nal
and get the profile. Based on this, reject the clip playback */
if (first_frame == 0 && codec_type_parse == CODEC_TYPE_H264 &&
@ -8015,6 +8030,7 @@ OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy(
struct vdec_bufferpayload *ptr_outputbuffer = NULL;
struct vdec_output_frameinfo *ptr_respbuffer = NULL;
auto_lock l(buf_lock);
nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
if (bufferAdd == NULL || nPortIndex >= drv_ctx.op_buf.actualcount) {
@ -8023,6 +8039,10 @@ OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy(
return OMX_ErrorBadParameter;
}
if (BITMASK_ABSENT(&m_out_bm_count, nPortIndex) || m_buffer_error) {
DEBUG_PRINT_ERROR("FTBProxy: ERROR: invalid buffer, nPortIndex %u", nPortIndex);
return OMX_ErrorBadParameter;
}
DEBUG_PRINT_LOW("FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
bufferAdd, bufferAdd->pBuffer);
/*Return back the output buffer to client*/
@ -9412,7 +9432,7 @@ int omx_vdec::async_message_process (void *context, void* message)
if (omxhdr && omxhdr->nFilledLen && !omx->m_need_turbo) {
omx->request_perf_level(VIDC_NOMINAL);
}
if (omx->output_use_buffer && omxhdr->pBuffer &&
if (!omx->m_enable_android_native_buffers && omx->output_use_buffer && omxhdr->pBuffer &&
vdec_msg->msgdata.output_frame.bufferaddr)
memcpy ( omxhdr->pBuffer, (void *)
((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr +