未验证,仅供参考,此方法感觉不是很好
先是AVFrame转QImage
#pragma execution_character_set("utf-8")static int decode_write_frame(AVCodecContext *avctx, AVFrame *frame, int *frame_count, AVPacket *pkt, int last)
{int len, got_frame;char buf[1024];len = avcodec_decode_video2(avctx, frame, &got_frame, pkt);if (len < 0) {printf("Error while decoding frame %d\n", *frame_count);return len;}if (got_frame) {printf("Saving frame %3d\n", *frame_count);QImage image(QSize(avctx->width, avctx->height), QImage::Format_RGB888);for(int h = 0; h < avctx->height; h++){for(int w = 0; w < avctx->width; w ++){int hh = h >> 1;int ww = w >> 1;int Y = frame->data[0][h * frame->linesize[0] + w];int U = frame->data[1][hh * (frame->linesize[1]) + ww];int V = frame->data[2][hh * (frame->linesize[2]) + ww];int C = Y - 16;int D = U - 128;int E = V - 128;int r = 298 * C + 409 * E + 128;int g = 298 * C - 100 * D - 208 * E + 128;int b = 298 * C + 516 * D + 128;r = qBound(0, r >> 8, 255);g = qBound(0, g >> 8, 255);b = qBound(0, b >> 8, 255);r = qBound(0, r, 255);g = qBound(0, g, 255);b = qBound(0, b, 255);QRgb rgb = qRgb(r, g, b);image.setPixel(QPoint(w, h), rgb);}}QString fname = QString("img") + QString::number(*frame_count) + ".jpg";image.save(fname);//pgm_save(frame->data[0], frame->linesize[0], avctx->width, avctx->height, buf);(*frame_count)++;}if (pkt->data) {pkt->size -= len;pkt->data += len;}return 0;
}
然后是QImage转AVFrame
#pragma execution_character_set("utf-8")QImage image = QPixmap::grabWindow(QApplication::desktop()->winId()).toImage();image = image.scaled(QSize(resize_width, resize_height));av_init_packet(pkt);pkt->data = NULL; // packet data will be allocated by the encoderpkt->size = 0;for (int h = 0; h < context->height; h++){for (int w = 0; w < context->width; w++){QRgb rgb = image.pixel(w, h);int r = qRed(rgb);int g = qGreen(rgb);int b = qBlue(rgb);int dy = ((66*r + 129*g + 25*b) >> 8) + 16;int du = ((-38*r + -74*g + 112*b) >> 8) + 128;int dv = ((112*r + -94*g + -18*b) >> 8) + 128;uchar yy = (uchar)dy;uchar uu = (uchar)du;uchar vv = (uchar)dv;frame->data[0][h * frame->linesize[0] + w] = yy;if(h % 2 == 0 && w % 2 == 0){frame->data[1][h/2 * (frame->linesize[1]) + w/2] = uu;frame->data[2][h/2 * (frame->linesize[2]) + w/2] = vv;}}}