Convert individual pixel values from RGB to YUV420 and save the frame - C++ -
i have been working rgb->yuv420 conversion sometime using ffmpeg library. tried sws_scale
functionality not working well. now, have decided convert each pixel individually, using colorspace conversion formulae. so, following code gets me few frames , allows me access individual r,g,b values of each pixel:
// read frames , save first 5 frames disk i=0; while((av_read_frame(pformatctx, &packet)>=0) && (i<5)) { // packet video stream? if(packet.stream_index==videostreamidx) { /// decode video frame avcodec_decode_video2(pcodecctx, pframe, &framefinished, &packet); // did video frame? if(framefinished) { i++; sws_scale(img_convert_ctx, (const uint8_t * const *)pframe->data, pframe->linesize, 0, pcodecctx->height, pframergb->data, pframergb->linesize); int x, y, r, g, b; uint8_t *p = pframergb->data[0]; for(y = 0; y < h; y++) { for(x = 0; x < w; x++) { r = *p++; g = *p++; b = *p++; printf(" %d-%d-%d ",r,g,b); } } saveframe(pframergb, pcodecctx->width, pcodecctx->height, i); } } // free packet allocated av_read_frame av_free_packet(&packet); }
i read online convert rgb->yuv420 or vice-versa, 1 should first convert yuv444 format. so, like: rgb->yuv444->yuv420. how implement in c++?
also, here saveframe()
function used above. guess have change little since yuv420 stores data differently. how take care of that?
void saveframe(avframe *pframe, int width, int height, int iframe) { file *pfile; char szfilename[32]; int y; // open file sprintf(szfilename, "frame%d.ppm", iframe); pfile=fopen(szfilename, "wb"); if(pfile==null) return; // write header fprintf(pfile, "p6\n%d %d\n255\n", width, height); // write pixel data for(y=0; y<height; y++) fwrite(pframe->data[0]+y*pframe->linesize[0], 1, width*3, pfile); // close file fclose(pfile); }
can please suggest? many thanks!!!
void saveframeyuv420p(avframe *pframe, int width, int height, int iframe) { file *pfile; char szfilename[32]; int y; // open file sprintf(szfilename, "frame%d.yuv", iframe); pfile=fopen(szfilename, "wb"); if(pfile==null) return; // write pixel data fwrite(pframe->data[0], 1, width*height, pfile); fwrite(pframe->data[1], 1, width*height/4, pfile); fwrite(pframe->data[2], 1, width*height/4, pfile); // close file fclose(pfile); }
on windows, can use irfanview see frames saved way. open frame raw, 24bpp format, provide width , height, , check box "yuv420".
Comments
Post a Comment