利用三星S3C6410源码实现同时压缩视频和图片

前段时间实现了利用三星S3C6410一边压缩视频生成H264文件一边抓取并压缩生成jpg图片。核心步骤如下:

  1. 视频压缩和图片压缩利用同一个handle。
    /* Codec set */
    /* Get capability */
    ret = ioctl(cam_c_fp , VIDIOC_QUERYCAP, &cap);

一边压缩视频:

if(frame_count == 1)
                    encoded_buf = mfc_encoder_exe(handle, g_yuv, YUV_FRAME_BUFFER_SIZE, 1, &encoded_size);
                else
                    encoded_buf = mfc_encoder_exe(handle, g_yuv, YUV_FRAME_BUFFER_SIZE, 0, &encoded_size);          

2.一边获取视频中的某一帧的数据:

 if (read(cam_c_fp, g_yuv_cc, g_YUV420_Frame_Buffer_Size) < 0) {
        perror("read()");}

3.读取完数据之后,因为图片压缩前的格式必须是yuv422的,而摄像头的数据格式为yuv420所以需要转化:

convert_yuv420p_to_yuv422_my( g_yuv_cc,g_yuv_c,g_codec_Width,g_codec_Height);

转化的具体实现为:

//平面YUV420转平面YUV422
static void convert_yuv420p_to_yuv422_my(unsigned char *src,unsigned char *dst,int width,int height)
{
int i,j;
unsigned char *pY420_0=src;
unsigned char *pY420_1=src+width;
unsigned char *pU420=src+width*height;
unsigned char *pV420=src+width*height*5/4;
unsigned char *pY422_0=dst;
unsigned char *pY422_1=dst+width*2;


for(i=0;i<height/2;i++)
{
for(j=0;j<width*2;j+=4)
{
*pY422_0++=*pY420_0++;
*pY422_1++=*pY420_1++;
*pY422_0++=*pU420;
*pY422_1++=*pU420++;

*pY422_0++=*pY420_0++;
*pY422_1++=*pY420_1++;
*pY422_0++=*pV420;
*pY422_1++=*pV420++;

}

pY420_0+=width;
pY420_1+=width;
pY422_0+=width*2;
pY422_1+=width*2;
}
}

4.转换完成之后就是简单的压缩过程了:

/* JPEG encoding */
    /* JPEG Handle initialization */
    jpg_handle = SsbSipJPEGEncodeInit();
    if (jpg_handle < 0)
        return;

    /* Set encoding configs */
    if((ret = SsbSipJPEGSetConfig(JPEG_SET_SAMPING_MODE, JPG_422)) != JPEG_OK)
        return;

        if((ret = SsbSipJPEGSetConfig(JPEG_SET_ENCODE_WIDTH, g_codec_Width)) != JPEG_OK)
        return;

        if((ret = SsbSipJPEGSetConfig(JPEG_SET_ENCODE_HEIGHT, g_codec_Height)) != JPEG_OK)
        return;

    if((ret = SsbSipJPEGSetConfig(JPEG_SET_ENCODE_QUALITY, JPG_QUALITY_LEVEL_2)) != JPEG_OK)
        return;

    if((ret = SsbSipJPEGSetConfig(JPEG_SET_ENCODE_THUMBNAIL, TRUE)) != JPEG_OK)
        return;

        //if((ret = SsbSipJPEGSetConfig(JPEG_SET_THUMBNAIL_WIDTH, 160)) != JPEG_OK)
        //  return;

        //   Main JPEG have to be multiple of Thumbnail resolution
        if((ret = SsbSipJPEGSetConfig(JPEG_SET_THUMBNAIL_WIDTH, g_Thumbnail_Width)) != JPEG_OK)
                return;


        //if((ret = SsbSipJPEGSetConfig(JPEG_SET_THUMBNAIL_HEIGHT, 120)) != JPEG_OK)
                //return;

       //   Main JPEG have to be multiple of Thumbnail resolution
        if((ret = SsbSipJPEGSetConfig(JPEG_SET_THUMBNAIL_HEIGHT, g_Thumbnail_Height)) != JPEG_OK)
                return;


    /* Get input buffer address */
        in_buf = SsbSipJPEGGetEncodeInBuf(jpg_handle, g_YUV422_Frame_Buffer_Size);
    if(in_buf == NULL)
        return;

    /* Copy YUV data from camera to JPEG driver */
        memcpy(in_buf, g_yuv_c, g_YUV422_Frame_Buffer_Size);

    /* Make Exif info parameters */
    memset(&ExifInfo, 0x00, sizeof(ExifFileInfo));
    makeExifParam(&ExifInfo);

    /* Encode YUV stream */
    ret = SsbSipJPEGEncodeExe(jpg_handle, &ExifInfo, JPEG_USE_HW_SCALER);    //with Exif

    /* Get output buffer address */
    out_buf = SsbSipJPEGGetEncodeOutBuf(jpg_handle, &jpg_size);
    if(out_buf == NULL)
        return;


    fwrite(out_buf, 1, jpg_size, jpg_fp);

    fclose(jpg_fp);
    SsbSipJPEGEncodeDeInit(jpg_handle);

    printf("CAPTURE SUCCESS\n");
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值