3D视频中,有的是上下格式的,但是无论是裸眼3D还是3D眼镜都需要左右格式的,下面就是转换的算法,利用ffmpeg解码,进行YUV切割,实现左右视频交织,可以在裸眼3D手机或者pad上观看3D效果。必须要先熟悉YUV数据格式。
FILE *yuvFile = fopen("yuv_file_width.yuv","ab");
if(!yuvFile)
return 0;
av_register_all();
AVFormatContext *pFormat = NULL;
if (avformat_open_input(&pFormat ,SRC_FILE,NULL,NULL) <0)
{
return 0;
}
AVCodecContext * video_dec_ctx = NULL;
AVCodec *video_dec = NULL;
if (avformat_find_stream_info(pFormat,NULL) <0)
{
return 0;
}
av_dump_format(pFormat,0,SRC_FILE,0);
int index = -1,i = 0;
for (i=0;inb_streams;i++)
{
if (pFormat->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
{
index = i;
break;
}
}
if (-1 == index)
{
printf("can‘t find the codec\n");
return -1;
}
video_dec_ctx = pFormat->streams[index]->codec;
video_dec = avcodec_find_decoder(video_dec_ctx->codec_id);
//源文件的格式上下文 解码器上下文 解码器 都已经找到 现在打开解码器
if(avcodec_open2(video_dec_ctx,video_dec,NULL) <0)
{
return 0;
}
//需要读取一帧数据 放在包里
AVPacket *video_pkt = new AVPacket;
av_init_packet(video_pkt);
while (1)
{
if(av_read_frame(pFormat,video_pkt)<0)
{
fclose(yuvFile);
delete video_pkt;
return 0;
}
if (pFormat->streams[video_pkt->stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
{
AVFrame *frame =avcodec_alloc_frame();
int got_pictrue = 0,ret = 0;
ret = avcodec_decode_video2(video_dec_ctx,frame,&got_pictrue,video_pkt);
if (ret <0)
{
continue;
}
if (got_pictrue)
{
printf("decode one frame is ok\n");
int height = video_dec_ctx->height/2;
int width = video_dec_ctx->width*2;
char *buf = new char[height*width*3/2];
memset(buf,0,height*width*3/2);
int y_tmp=0,i=0;
int u_tmp = width/2*height*2;
int v_tmp = u_tmp + width/4*height/2*2;
for (i=0;idata[0]+i*frame->linesize[0],width/2);
y_tmp += width/2;
tmp = i+height;
memcpy(buf+y_tmp,frame->data[0]+tmp*frame->linesize[0],width/2);
y_tmp += width/2;
if (idata[1]+i*frame->linesize[1],width/4);
u_tmp += width/4;
tmp = i+height/2;
memcpy(buf+u_tmp,frame->data[1]+tmp*frame->linesize[1],width/4);
u_tmp += width/4;
memcpy(buf+v_tmp,frame->data[2]+i*frame->linesize[2],width/4);
v_tmp += width/4;
tmp = i+height/2;
memcpy(buf+v_tmp,frame->data[2]+tmp*frame->linesize[2],width/4);
v_tmp += width/4;
}
}
int frame_height = height;
int frame_width = width/2;
char *frame_buf = new char[frame_height*frame_width*3/2];
memset(frame_buf,0,frame_height*frame_width*3/2);
int tmp=0;
for (i=0;idata[0]+i*frame->linesize[0],width);
a += width;
}
for (i=0;idata[1]+i*frame->linesize[1],width/2);
a += width/2;
}
for (i=0;idata[2]+i*frame->linesize[2],width/2);
a += width/2;
}
fwrite(frame_buf,1,frame_height*frame_width*3/2,yuvFile);
delete[] frame_buf;
delete[] buf;
frame_buf = NULL;
buf = NULL;
}
avcodec_free_frame(&frame);
}
}
fclose(yuvFile);
delete video_pkt;