diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2013-12-05 17:26:02 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2013-12-05 17:26:02 -0800 |
commit | 50ae6471bf27b2bc840c8a5ea4a77e5f7201e7fd (patch) | |
tree | 50cb7536f4777d2dd0bccc028ef13cfb179c1522 | |
parent | 56728d2cfe6d772232f27acaabee545716c0312b (diff) | |
parent | 0405148deab7219f9d79ae521601c7bf29966702 (diff) | |
download | media-linaro-master.tar.gz |
Merge commit '0405148deab7219f9d79ae521601c7bf29966702' into HEADlinaro-masteridea133
-rw-r--r-- | mm-video-legacy/vidc/venc/src/omx_video_base.cpp | 2 | ||||
-rwxr-xr-x | mm-video-v4l2/vidc/vdec/inc/omx_vdec.h | 19 | ||||
-rwxr-xr-x | mm-video-v4l2/vidc/vdec/src/omx_vdec_msm8974.cpp | 137 | ||||
-rwxr-xr-x | mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h | 3 | ||||
-rw-r--r--[-rwxr-xr-x] | mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp | 75 |
5 files changed, 198 insertions, 38 deletions
diff --git a/mm-video-legacy/vidc/venc/src/omx_video_base.cpp b/mm-video-legacy/vidc/venc/src/omx_video_base.cpp index 9c225bd..84099b2 100644 --- a/mm-video-legacy/vidc/venc/src/omx_video_base.cpp +++ b/mm-video-legacy/vidc/venc/src/omx_video_base.cpp @@ -2751,7 +2751,7 @@ OMX_ERRORTYPE omx_video::allocate_input_buffer( #ifdef USE_ION m_pInput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sInPortDef.nBufferSize, &m_pInput_ion[i].ion_alloc_data, - &m_pInput_ion[i].fd_ion_data,ION_FLAG_CACHED); + &m_pInput_ion[i].fd_ion_data,0); if(m_pInput_ion[i].ion_device_fd < 0) { DEBUG_PRINT_ERROR("\nERROR:ION device open() Failed"); return OMX_ErrorInsufficientResources; diff --git a/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h b/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h index 765af59..00d5e6e 100755 --- a/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h +++ b/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h @@ -721,12 +721,26 @@ class omx_vdec: public qc_omx_component nativebuffer native_buffer[MAX_NUM_INPUT_OUTPUT_BUFFERS]; #endif - + class auto_lock { + public: + auto_lock(pthread_mutex_t *lock) + : mLock(lock) { + if (mLock) + pthread_mutex_lock(mLock); + } + ~auto_lock() { + if (mLock) + pthread_mutex_unlock(mLock); + } + private: + pthread_mutex_t *mLock; + }; //************************************************************* //*******************MEMBER VARIABLES ************************* //************************************************************* pthread_mutex_t m_lock; pthread_mutex_t c_lock; + pthread_mutex_t e_lock; //sem to handle the minimum procesing of commands sem_t m_cmd_lock; bool m_error_propogated; @@ -959,6 +973,9 @@ class omx_vdec: public qc_omx_component allocate_color_convert_buf client_buffers; #endif struct video_decoder_capability m_decoder_capability; +#ifdef _MSM8974_ + void send_codec_config(); +#endif }; #ifdef _MSM8974_ diff --git a/mm-video-v4l2/vidc/vdec/src/omx_vdec_msm8974.cpp b/mm-video-v4l2/vidc/vdec/src/omx_vdec_msm8974.cpp index e702c62..9887143 100755 --- a/mm-video-v4l2/vidc/vdec/src/omx_vdec_msm8974.cpp +++ b/mm-video-v4l2/vidc/vdec/src/omx_vdec_msm8974.cpp @@ -611,6 +611,7 @@ omx_vdec::omx_vdec(): m_error_propogated(false), m_vendor_config.pData = NULL; pthread_mutex_init(&m_lock, NULL); pthread_mutex_init(&c_lock, NULL); + pthread_mutex_init(&e_lock, NULL); sem_init(&m_cmd_lock,0,0); streaming[CAPTURE_PORT] = streaming[OUTPUT_PORT] = false; @@ -729,6 +730,7 @@ omx_vdec::~omx_vdec() close(drv_ctx.video_driver_fd); pthread_mutex_destroy(&m_lock); pthread_mutex_destroy(&c_lock); + pthread_mutex_destroy(&e_lock); sem_destroy(&m_cmd_lock); if (perf_flag) { DEBUG_PRINT_HIGH("--> TOTAL PROCESSING TIME"); @@ -2156,6 +2158,7 @@ OMX_ERRORTYPE omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp, } else if (cmd == OMX_CommandFlush) { DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandFlush issued" "with param1: %lu", param1); + send_codec_config(); if (OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1) { BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING); } @@ -2208,6 +2211,7 @@ OMX_ERRORTYPE omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp, DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortDisable issued" "with param1: %lu", param1); if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) { + codec_config_flag = false; m_inp_bEnabled = OMX_FALSE; if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle) && release_input_done()) { @@ -3817,11 +3821,13 @@ OMX_ERRORTYPE omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE OMX_ERRORTYPE omx_vdec::allocate_extradata() { #ifdef USE_ION + auto_lock extradata_lock(&e_lock); if (drv_ctx.extradata_info.buffer_size) { if (drv_ctx.extradata_info.ion.ion_alloc_data.handle) { munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size); close(drv_ctx.extradata_info.ion.fd_ion_data.fd); free_ion_memory(&drv_ctx.extradata_info.ion); + memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info)); } drv_ctx.extradata_info.size = (drv_ctx.extradata_info.size + 4095) & (~4095); drv_ctx.extradata_info.ion.ion_device_fd = alloc_map_ion_memory( @@ -3850,6 +3856,7 @@ OMX_ERRORTYPE omx_vdec::allocate_extradata() void omx_vdec::free_extradata() { #ifdef USE_ION + auto_lock extradata_lock(&e_lock); if (drv_ctx.extradata_info.uaddr) { munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size); close(drv_ctx.extradata_info.ion.fd_ion_data.fd); @@ -4322,36 +4329,39 @@ OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr) setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT; memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index], sizeof (vdec_bufferpayload)); + + if (!dynamic_buf_mode) { #ifdef _ANDROID_ - if (m_enable_android_native_buffers) { - if (!secure_mode) { - if (drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) { - munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr, - drv_ctx.ptr_outputbuffer[index].mmaped_size); - } - } - drv_ctx.ptr_outputbuffer[index].pmem_fd = -1; - } else { -#endif - if (drv_ctx.ptr_outputbuffer[0].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem) { + if (m_enable_android_native_buffers) { if (!secure_mode) { - DEBUG_PRINT_LOW("\n unmap the output buffer fd = %d", - drv_ctx.ptr_outputbuffer[0].pmem_fd); - DEBUG_PRINT_LOW("\n unmap the ouput buffer size=%d address = %p", - drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount, - drv_ctx.ptr_outputbuffer[0].bufferaddr); - munmap (drv_ctx.ptr_outputbuffer[0].bufferaddr, - drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount); + if (drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) { + munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr, + drv_ctx.ptr_outputbuffer[index].mmaped_size); + } } - close (drv_ctx.ptr_outputbuffer[0].pmem_fd); - drv_ctx.ptr_outputbuffer[0].pmem_fd = -1; + drv_ctx.ptr_outputbuffer[index].pmem_fd = -1; + } else { +#endif + if (drv_ctx.ptr_outputbuffer[0].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem) { + if (!secure_mode) { + DEBUG_PRINT_LOW("\n unmap the output buffer fd = %d", + drv_ctx.ptr_outputbuffer[0].pmem_fd); + DEBUG_PRINT_LOW("\n unmap the ouput buffer size=%d address = %p", + drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount, + drv_ctx.ptr_outputbuffer[0].bufferaddr); + munmap (drv_ctx.ptr_outputbuffer[0].bufferaddr, + drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount); + } + close (drv_ctx.ptr_outputbuffer[0].pmem_fd); + drv_ctx.ptr_outputbuffer[0].pmem_fd = -1; #ifdef USE_ION - free_ion_memory(&drv_ctx.op_buf_ion_info[0]); + free_ion_memory(&drv_ctx.op_buf_ion_info[0]); #endif - } + } #ifdef _ANDROID_ - } + } #endif + } //!dynamic_buf_mode if (release_output_done()) { free_extradata(); } @@ -5178,13 +5188,6 @@ OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_ERRORTYPE ret1 = OMX_ErrorNone; unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount; - if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { - codec_config_flag = true; - DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__); - } else { - codec_config_flag = false; - } - if (m_state == OMX_StateInvalid) { DEBUG_PRINT_ERROR("Empty this buffer in Invalid State\n"); return OMX_ErrorInvalidState; @@ -5243,6 +5246,11 @@ OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp, return OMX_ErrorBadParameter; } + if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { + codec_config_flag = true; + DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__); + } + DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%lu)", buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen); if (arbitrary_bytes) { @@ -5500,6 +5508,9 @@ OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE h DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver\n"); return OMX_ErrorHardware; } + if (codec_config_flag && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) { + codec_config_flag = false; + } if (!streaming[OUTPUT_PORT]) { enum v4l2_buf_type buf_type; int ret,r; @@ -7369,12 +7380,20 @@ void omx_vdec::free_input_buffer_header() free (m_inp_mem_ptr); m_inp_mem_ptr = NULL; } - /* We just freed all the buffer headers, every thing in m_input_free_q - * is now invalid */ + /* We just freed all the buffer headers, every thing in m_input_free_q, + * pdest_frame, and psource_frame is now invalid */ while (m_input_free_q.m_size) { unsigned address, p2, id; m_input_free_q.pop_entry(&address, &p2, &id); } + /* We just freed all the buffer headers, every thing in m_input_pending_q, + * is now invalid too*/ + while (m_input_pending_q.m_size) { + unsigned address, p2, id; + m_input_pending_q.pop_entry(&address, &p2, &id); + } + pdest_frame = NULL; + psource_frame = NULL; if (drv_ctx.ptr_inputbuffer) { DEBUG_PRINT_LOW("\n Free Driver Context pointer"); free (drv_ctx.ptr_inputbuffer); @@ -7945,9 +7964,17 @@ void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr) int enable = 0; OMX_U32 mbaff = 0; int buf_index = p_buf_hdr - m_out_mem_ptr; + if (buf_index >= drv_ctx.extradata_info.count) { + DEBUG_PRINT_ERROR("handle_extradata: invalid index(%d) max(%d)", + buf_index, drv_ctx.extradata_info.count); + return; + } struct msm_vidc_panscan_window_payload *panscan_payload = NULL; OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr) + p_buf_hdr->nOffset; + + auto_lock extradata_lock(&e_lock); + if (!drv_ctx.extradata_info.uaddr) { return; } @@ -8046,6 +8073,9 @@ void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr) } consumed_len += data->nSize; data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize); + if (data->nSize) { + break; + } } if (!secure_mode && (client_extradata & OMX_FRAMEINFO_EXTRADATA)) { p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA; @@ -8929,3 +8959,46 @@ void omx_vdec::buf_ref_remove(OMX_U32 fd, OMX_U32 offset) } pthread_mutex_unlock(&m_lock); } + +void omx_vdec::send_codec_config() { + if (codec_config_flag) { + unsigned p1 = 0; // Parameter - 1 + unsigned p2 = 0; // Parameter - 2 + unsigned ident = 0; + pthread_mutex_lock(&m_lock); + DEBUG_PRINT_LOW("\n Check Queue for codec_config buffer \n"); + while (m_etb_q.m_size) { + m_etb_q.pop_entry(&p1,&p2,&ident); + if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) { + if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { + if (empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\ + (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) { + DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure"); + omx_report_error(); + } + } else { + DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2); + m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2); + } + } else if (ident == OMX_COMPONENT_GENERATE_ETB) { + if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { + if (empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\ + (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) { + DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure"); + omx_report_error (); + } + } else { + pending_input_buffers++; + DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d", + (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers); + empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2); + } + } else if (ident == OMX_COMPONENT_GENERATE_EBD) { + DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_EBD %p", + (OMX_BUFFERHEADERTYPE *)p1); + empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1); + } + } + pthread_mutex_unlock(&m_lock); + } +} diff --git a/mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h b/mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h index 7b4b250..557ba2c 100755 --- a/mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h +++ b/mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h @@ -251,6 +251,7 @@ class venc_dev }; int stopped; + int resume_in_stopped; bool m_max_allowed_bitrate_check; pthread_t m_tid; bool async_thread_created; @@ -300,6 +301,8 @@ class venc_dev bool venc_set_slice_delivery_mode(OMX_U32 enable); bool venc_set_extradata(OMX_U32 extra_data); bool venc_set_idr_period(OMX_U32 nPFrames, OMX_U32 nIDRPeriod); + bool venc_reconfig_reqbufs(); + #ifdef MAX_RES_1080P OMX_U32 pmem_free(); OMX_U32 pmem_allocate(OMX_U32 size, OMX_U32 alignment, OMX_U32 count); diff --git a/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp b/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp index ecb7c6b..ef7de6f 100755..100644 --- a/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp +++ b/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp @@ -677,6 +677,7 @@ bool venc_dev::venc_open(OMX_U32 codec) m_sOutput_buff_property.mincount = m_sOutput_buff_property.actualcount = bufreq.count; + resume_in_stopped = 0; metadatamode = 0; control.id = V4L2_CID_MPEG_VIDEO_HEADER_MODE; @@ -1438,7 +1439,8 @@ bool venc_dev::venc_set_config(void *configData, OMX_INDEXTYPE index) unsigned venc_dev::venc_stop( void) { struct venc_msg venc_msg; - int rc = 0; + struct v4l2_requestbuffers bufreq; + int rc = 0, ret = 0; if (!stopped) { enum v4l2_buf_type cap_type; @@ -1452,6 +1454,17 @@ unsigned venc_dev::venc_stop( void) cap_type, rc); } else streaming[OUTPUT_PORT] = false; + + DEBUG_PRINT_LOW("Releasing registered buffers from driver on o/p port"); + bufreq.memory = V4L2_MEMORY_USERPTR; + bufreq.count = 0; + bufreq.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + ret = ioctl(m_nDriver_fd, VIDIOC_REQBUFS, &bufreq); + + if (ret) { + DEBUG_PRINT_ERROR("\nERROR: VIDIOC_REQBUFS OUTPUT MPLANE Failed \n "); + return false; + } } if (!rc && streaming[CAPTURE_PORT]) { @@ -1463,11 +1476,25 @@ unsigned venc_dev::venc_stop( void) cap_type, rc); } else streaming[CAPTURE_PORT] = false; + + DEBUG_PRINT_LOW("Releasing registered buffers from driver on capture port"); + bufreq.memory = V4L2_MEMORY_USERPTR; + bufreq.count = 0; + bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + ret = ioctl(m_nDriver_fd, VIDIOC_REQBUFS, &bufreq); + + if (ret) { + DEBUG_PRINT_ERROR("\nERROR: VIDIOC_REQBUFS CAPTURE MPLANE Failed \n "); + return false; + } } - if (!rc) { + if (!rc && !ret) { venc_stop_done(); stopped = 1; + /*set flag to re-configure when started again*/ + resume_in_stopped = 1; + } } @@ -1522,7 +1549,9 @@ unsigned venc_dev::venc_start(void) { enum v4l2_buf_type buf_type; int ret,r; - DEBUG_PRINT_HIGH("\n %s(): Check Profile/Level set in driver before start", + struct v4l2_control control = {0}; + + DEBUG_PRINT_HIGH("%s(): Check Profile/Level set in driver before start", __func__); if (!venc_set_profile_level(0, 0)) { @@ -1535,6 +1564,12 @@ unsigned venc_dev::venc_start(void) venc_config_print(); + if(resume_in_stopped){ + /*set buffercount when restarted*/ + venc_reconfig_reqbufs(); + resume_in_stopped = 0; + } + /* Check if slice_delivery mode is enabled & max slices is sufficient for encoding complete frame */ if (slice_mode.enable && multislice.mslice_size && (m_sVenc_cfg.input_width * m_sVenc_cfg.input_height)/(256 * multislice.mslice_size) >= MAX_SUPPORTED_SLICES_PER_FRAME) { @@ -1552,6 +1587,15 @@ unsigned venc_dev::venc_start(void) return 1; streaming[CAPTURE_PORT] = true; + + control.id = V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_SEQ_HEADER; + control.value = 1; + ret = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); + if (ret) { + DEBUG_PRINT_ERROR("failed to request seq header"); + return 1; + } + stopped = 0; return 0; } @@ -1588,6 +1632,29 @@ void venc_dev::venc_config_print() } +bool venc_dev::venc_reconfig_reqbufs() +{ + struct v4l2_requestbuffers bufreq; + + bufreq.memory = V4L2_MEMORY_USERPTR; + bufreq.count = m_sInput_buff_property.actualcount; + bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) { + DEBUG_PRINT_ERROR("\n VIDIOC_REQBUFS OUTPUT_MPLANE Failed when resume\n"); + return false; + } + + bufreq.memory = V4L2_MEMORY_USERPTR; + bufreq.count = m_sOutput_buff_property.actualcount; + bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) + { + DEBUG_PRINT_ERROR("\nERROR: Request for setting o/p buffer count failed when resume\n"); + return false; + } + return true; +} + unsigned venc_dev::venc_flush( unsigned port) { struct v4l2_encoder_cmd enc; @@ -2521,7 +2588,7 @@ bool venc_dev::venc_set_entropy_config(OMX_BOOL enable, OMX_U32 i_cabac_level) } DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); - entropy.longentropysel=control.value; + entropy.cabacmodel=control.value; } else if (!enable) { control.value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC; control.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE; |