yuv420p转jpg图片

yuv420p转jpg图片

int yuv420p_to_jpeg(const char * filename, const char* pdata,int image_width,int image_height, int quality)
{   
    struct jpeg_compress_struct cinfo;  
    struct jpeg_error_mgr jerr;  
    cinfo.err = jpeg_std_error(&jerr);  
    jpeg_create_compress(&cinfo);  

    FILE * outfile;    // target file  
    if ((outfile = fopen(filename, "wb")) == NULL) {  
        fprintf(stderr, "can't open %s\n", filename);  
        exit(1);  
    }  
    jpeg_stdio_dest(&cinfo, outfile);  

    cinfo.image_width = image_width;  // image width and height, in pixels  
    cinfo.image_height = image_height;  
    cinfo.input_components = 3;    // # of color components per pixel  
    cinfo.in_color_space = JCS_YCbCr;  //colorspace of input image  
    jpeg_set_defaults(&cinfo);  
    jpeg_set_quality(&cinfo, quality, TRUE );  

    //  
    //  cinfo.raw_data_in = TRUE;  
    cinfo.jpeg_color_space = JCS_YCbCr;  
    cinfo.comp_info[0].h_samp_factor = 2;  
    cinfo.comp_info[0].v_samp_factor = 2;  
    /  

    jpeg_start_compress(&cinfo, TRUE);  

    JSAMPROW row_pointer[1];

    unsigned char *yuvbuf;
    if((yuvbuf=(unsigned char *)malloc(image_width*3))!=NULL)
        memset(yuvbuf,0,image_width*3);

    unsigned char *ybase,*ubase;
    ybase=pdata;
    ubase=pdata+image_width*image_height;  
    int j=0;
    while (cinfo.next_scanline < cinfo.image_height) 
    {
        int idx=0;
        for(int i=0;i<image_width;i++)
        { 
            yuvbuf[idx++]=ybase[i + j * image_width];
            yuvbuf[idx++]=ubase[j/2 * image_width+(i/2)*2];
            yuvbuf[idx++]=ubase[j/2 * image_width+(i/2)*2+1];    
        }
        row_pointer[0] = yuvbuf;
        jpeg_write_scanlines(&cinfo, row_pointer, 1);
        j++;
    }
    jpeg_finish_compress(&cinfo);  
    jpeg_destroy_compress(&cinfo);  
    fclose(outfile);  
    return 0;  
}

从AVFrame提取yuv数据到char * buf

	//如果是视频
	else if (pstream_info[i].dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO)
	{
		int new_videosize = pkt.size;
		int video_decode_size = avpicture_get_size(pstream_info->dec_ctx->pix_fmt, Zoom_Width,Zoom_Height);
		uint8_t * video_decode_buf =( uint8_t *)calloc(1,video_decode_size * 3 * sizeof(char)); //最大分配的空间,能满足yuv的各种格式

		// Decode video frame
		avcodec_decode_video2(pstream_info->dec_ctx, pDecodeFrame, &frameFinished,&pkt);
		if(frameFinished) 
		{
			if (pstream_info->dec_ctx->pix_fmt == AV_PIX_FMT_YUV420P) //如果是yuv420p的
			{
				for(i = 0 ; i < pstream_info->dec_ctx->height ; i++)
				{
					memcpy(video_decode_buf+pstream_info->dec_ctx->width*i,
						pDecodeFrame->data[0]+pDecodeFrame->linesize[0]*i,
						pstream_info->dec_ctx->width);
				}
				for(j = 0 ; j < pstream_info->dec_ctx->height/2 ; j++)
				{
					memcpy(video_decode_buf+pstream_info->dec_ctx->width*i+pstream_info->dec_ctx->width/2*j,
						pDecodeFrame->data[1]+pDecodeFrame->linesize[1]*j,
						pstream_info->dec_ctx->width/2);
				}
				for(k  =0 ; k < pstream_info->dec_ctx->height/2 ; k++)
				{
					memcpy(video_decode_buf+pstream_info->dec_ctx->width*i+pstream_info->dec_ctx->width/2*j+pstream_info->dec_ctx->width/2*k,
						pDecodeFrame->data[2]+pDecodeFrame->linesize[2]*k, 
						pstream_info->dec_ctx->width/2);
				}
			}
			else if (pstream_info->dec_ctx->pix_fmt == AV_PIX_FMT_YUV422P)//如果是yuv422p的
			{
				for(i = 0 ; i < pstream_info->dec_ctx->height ; i++)
				{
					memcpy(video_decode_buf+pstream_info->dec_ctx->width*i,
						pDecodeFrame->data[0]+pDecodeFrame->linesize[0]*i,
						pstream_info->dec_ctx->width);
				}
				for(j = 0 ; j < pstream_info->dec_ctx->height ; j++)
				{
					memcpy(video_decode_buf+pstream_info->dec_ctx->width*i+pstream_info->dec_ctx->width/2*j,
						pDecodeFrame->data[1]+pDecodeFrame->linesize[1]*j,
						pstream_info->dec_ctx->width/2);
				}
				for(k  =0 ; k < pstream_info->dec_ctx->height ; k++)
				{
					memcpy(video_decode_buf+pstream_info->dec_ctx->width*i+pstream_info->dec_ctx->width/2*j+pstream_info->dec_ctx->width/2*k,
						pDecodeFrame->data[2]+pDecodeFrame->linesize[2]*k, 
						pstream_info->dec_ctx->width/2);
				}
			}
			else
			{
				//可扩展
			}
			video_decode_size = avpicture_get_size(pstream_info->dec_ctx->pix_fmt, pstream_info->dec_ctx->width,pstream_info->dec_ctx->height);
			new_videosize = video_decode_size; 

			//缩放或格式转换
			if (pstream_info->dec_ctx->width != Zoom_Width || 
				pstream_info->dec_ctx->height !=  Zoom_Height ||
				pstream_info->dec_ctx->pix_fmt != Zoom_pix_fmt)
			{
				    new_videosize = VideoScaleYuvZoom(Is_flip,pstream_info->dec_ctx->width ,pstream_info->dec_ctx->height,(int)pstream_info->dec_ctx->pix_fmt,
					Zoom_Width,Zoom_Height,Zoom_pix_fmt,video_decode_buf);
			}
			//这里可以取出数据
			frame_info->stream_idx = pstream_info->stream_idx;
			//frame_info->pts = pDecodeFrame->pkt_pts * 1000 * av_q2d(pstream_info->stream->time_base);  //转化成毫秒
			frame_info->pts = pDecodeFrame->pkt_pts ;
			frame_info->timebase_den = pstream_info->stream->time_base.den;  
			frame_info->timebase_num = pstream_info->stream->time_base.num; 
			frame_info->bufsize = new_videosize;
			memcpy(frame_info->buf,video_decode_buf,new_videosize);
		}
		else
		{
			//缓存
			frame_info->stream_idx = pstream_info->stream_idx;
			frame_info->pts = 0;
			frame_info->timebase_den = 0;
			frame_info->timebase_num = 0;
			frame_info->bufsize = 0;
			memset(frame_info->buf,0,MAX_FRAME_SIZE);
		}
		if (video_decode_buf)
		{
			free(video_decode_buf);
			video_decode_buf = NULL;
		}
		video_decode_size = 0;
	}

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值