FFMPEG中的swscale提供了視頻原始數據(YUV420,YUV422,YUV444,RGB24...)之間的轉換,分辨率變換等操作,使用起來十分方便,在這里記錄一下它的用法。
swscale主要用於在2個AVFrame之間進行轉換。
下面來看一個視頻解碼的簡單例子,這個程序完成了對"北京移動開發者大會茶歇視頻2.flv"(其實就是優酷上的一個普通視頻)的解碼工作,並將解碼后的數據保存為原始數據文件(例如YUV420,YUV422,RGB24等等)。其中略去了很多的代碼。
解碼H264
int i; //YUV420 for(i=0;i<576;i++) {//fwrite(buf + i * wrap, 1, xsize, f); memcpy(overlay->pixels[0]+i*1280, pFrame_->data[0]+i*pFrame_->linesize[0], 720); } for(i=0;i<288;i++) { memcpy(overlay->pixels[2]+i*640, pFrame_->data[1]+i*pFrame_->linesize[1], 360); memcpy(overlay->pixels[1]+i*640, pFrame_->data[2]+i*pFrame_->linesize[2], 360); }代碼轉換yuv422
int k=0,y,x; //yuv420 -> yuv422 for( y=0;y<576;y++) { for( x=0;x<720;x++) { yuv422[k++] = pFrame_->data[0][y*pFrame_->linesize[0]+x]; yuv422[k++] = x%2==0?pFrame_->data[1][(y/2)*pFrame_->linesize[1]+x/2]:pFrame_->data[2][(y/2)*pFrame_->linesize[2]+x/2]; } } memcpy(overlay->pixels[0],yuv422, codec_->width*codec_->height*2);采用swscale轉換
int numBytes = avpicture_get_size(AV_PIX_FMT_YUYV422, codec_->width, codec_->height); uint8_t* yuv422 = (uint8_t *)av_malloc(numBytes*sizeof(uint8_t)); avpicture_fill((AVPicture *)pFrameYUV, yuv422, AV_PIX_FMT_YUYV422, codec_->width, codec_->height); //while img_convert_ctx = sws_getContext(codec_->width, codec_->height, codec_->pix_fmt, codec_->width, codec_->height, AV_PIX_FMT_YUYV422, 2, NULL, NULL, NULL); sws_scale(img_convert_ctx, (const uint8_t* const*) pFrame_->data, pFrame_->linesize, 0, codec_->height, pFrameYUV->data,pFrameYUV->linesize); memcpy(overlay->pixels[0],yuv422, codec_->width*codec_->height*2);