Hardware Platform: Atmel SAMA5D3 SoC + OV2640 Camera SensorAndroid version: 4.2.2
The mediaserver process is the container process of the Camera Service. It dynamically loads the Camera HAL and Gralloc HAL. Video data frames must first arrive at the Camera hardware abstraction layer from the Camera driver. On the Camera hardware abstraction layer, video data frames are copied from the video capture buffer to the gralloc buffer.
As a display server, the surfaceflinger process dynamically loads HWComposer HAL and Gralloc HAL. On the HWComposer hardware abstraction layer, data frames are copied from gralloc buffer to the video output buffer.
After the above process, the images collected by Camera Sensor are finally displayed on the display screen through lcdc heo.
In the figure, the red line shows the stream direction of the video data frame, and the two ends of the red line without arrows are the same piece of memory.
Three memory blocks are involved: video capture buffer/dev/video1gralloc buffer anonymous shared memory mediaserver process and surfacelinger process can both access this memory video output buffer/dev/video0
Two data copy operations are performed, as follows: media server process Camera HAL video capture buffer-> gralloc buffer
Surfaceflinger process HWCompser HAL gralloc buffer-> video output buffer
Allocation of video capture buffer and memory ingWhy? Http://www.bkjia.com/kf/ware/vc/ "target =" _ blank "class =" keylink "> flock + seek + Cgo8cHJlIGNsYXNzPQ =" brush: java; "> ret = ioctl (fp, VIDIOC_REQBUFS, & req );
Memory ing CameraHardwareSam::StartPreviewInternal
mPreviewHeap = mGetMemoryCb((int)mV4L2Camera->getCameraFd(), aligned_buffer_size, kBufferCount, 0);
Obtain the copy of gralloc buffer and video data frames from video capture buffer to gralloc buffer.Https://github.com/Android4SAM/platform_hardware_atmel/blob/android4sam_v4.0/camera/CameraHardwareSam.cpp
CameraHardwareSam
::PreviewThread
if (mPreviewWindow && mGrallocHal) { buffer_handle_t *buf_handle; int stride; if (0 != mPreviewWindow->dequeue_buffer(mPreviewWindow, &buf_handle, &stride)) { ALOGE("Could not dequeue gralloc buffer!\n"); goto callbacks; } void *vaddr; if (!mGrallocHal->lock(mGrallocHal, *buf_handle, GRALLOC_USAGE_SW_WRITE_OFTEN, 0, 0, width, height, &vaddr)) { char *frame = ((char *)mPreviewHeap->data) + offset; // the code below assumes YUV, not RGB { int h; char *src = frame; char *ptr = (char *)vaddr; memcpy(ptr, src, frame_size); //YUY2toYV12(frame, vaddr, width, height); } mGrallocHal->unlock(mGrallocHal, *buf_handle); } else ALOGE("%s: could not obtain gralloc buffer", __func__); if (0 != mPreviewWindow->enqueue_buffer(mPreviewWindow, buf_handle)) { ALOGE("Could not enqueue gralloc buffer!\n"); goto callbacks; } }
Allocation of video output buffer and memory ingHttps://github.com/Android4SAM/platform_hardware_atmel/blob/android4sam_v4.0/hwcomposer/hwcomposer.cpphttps://github.com/Android4SAM/platform_hardware_atmel/blob/android4sam_v4.0/hwcomposer/v4l2_utils.cpp
Apply for video ouput buffer
Hwc_prepare->Assign_heo_overlay_window-> v4l2_overlay_req_buf
ret = ioctl(win->fd, VIDIOC_REQBUFS, &reqbuf);
Memory ing
Hwc_prepare->Assign_heo_overlay_window->
V4l2_overlay_map_buf
*len = buf.length; *start = mmap(NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, buf.m.offset);
Copying video data frames from gralloc buffer to video output buffer
Hwc_set->Copy_heo_src_content
for (unsigned int i = 0; i < cur_layer->visibleRegionScreen.numRects; i++) { uint8_t *cur_dst_addr = dst_addr; uint8_t *cur_src_addr = src_addr; for (int j = 0; j < h ; j++) { memcpy(cur_dst_addr, cur_src_addr, cpy_size); cur_dst_addr = &cur_dst_addr[cpy_size]; cur_src_addr = &cur_src_addr[(cur_layer->displayFrame.right - cur_layer->displayFrame.left) * (prev_handle->uiBpp / 8)]; } cur_rect++; }