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
从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;
}