'Error submitting the frame for encoding when submitting NV12 texture
I'm trying to encode D3D11 NV12 Texture on QSV encoder but getting [h264_qsv @ 00000244ce6f50c0] Error submitting the frame for encoding.
Main:
int width = 1920;
int height = 1080;
FILE* outfile;
fopen_s(&outfile, "D:\\Sources\\D3D11QSV\\x64\\Debug\\outfile.264", "wb");
const AVCodec* codec = avcodec_find_encoder_by_name("h264_qsv");
AVCodecContext* ctx = avcodec_alloc_context3(codec);
ctx->width = width;
ctx->height = height;
ctx->time_base = AVRational{ 1, 60 };
ctx->framerate = AVRational{ 60, 1 };
ctx->slices = 1;
ctx->sw_pix_fmt = AV_PIX_FMT_NV12;
ctx->pix_fmt = AV_PIX_FMT_NV12;
ctx->bit_rate = 400000;
ctx->gop_size = 10;
ctx->max_b_frames = 1;
auto status = avcodec_open2(ctx, codec, NULL);
if (status < 0) {
std::cout << "Open codec error!\n";
}
AVFrame* sw_frame = av_frame_alloc();
sw_frame->format = ctx->sw_pix_fmt;
sw_frame->width = ctx->width;
sw_frame->height = ctx->height;
status = av_frame_get_buffer(sw_frame, 0);
fill_frame(sw_frame, ctx);
Filling the frame:
auto ret = 0;
if (ret < 0) {
fprintf(stderr, "Could not allocate the video frame data\n");
exit(1);
}
int i, y, x, c = 0;
for (i = 0; i < 60; i++) {
fflush(stdout);
ret = av_frame_make_writable(frame);
auto texture = create_texture();
auto desc = (AVD3D11FrameDescriptor*)frame->buf[0]->data;
desc->texture = (ID3D11Texture2D*)texture;
desc->index = 0;
frame->data[0] = (std::uint8_t*)texture;
frame->data[1] = 0;
frame->linesize[0] = width * 4;
frame->pts = i;
encode(frame, ctx);
}
Creating Texture:
D3D11_TEXTURE2D_DESC const desc = CD3D11_TEXTURE2D_DESC(
DXGI_FORMAT_NV12, // HoloLens PV camera format, common for video sources
width, // Width of the video frames
height, // Height of the video frames
1, // Number of textures in the array
1, // Number of miplevels in each texture
D3D11_BIND_SHADER_RESOURCE, // We read from this texture in the shader
D3D11_USAGE_DYNAMIC, // Because we'll be copying from CPU memory
D3D11_CPU_ACCESS_WRITE // We only need to write into the texture
);
ID3D11Device* pd3dDevice = create_d3d11_device();
ID3D11Texture2D* pTexture = NULL;
HRESULT err = pd3dDevice->CreateTexture2D(&desc, nullptr, &pTexture);
if (SUCCEEDED(err)) {
D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc = CD3D11_SHADER_RESOURCE_VIEW_DESC(
pTexture,
D3D11_SRV_DIMENSION_TEXTURE2D,
DXGI_FORMAT_R8_UNORM
);
ID3D11ShaderResourceView* texSRV = NULL;
err = pd3dDevice->CreateShaderResourceView(pTexture,
&SRVDesc, &texSRV);
D3D11_SHADER_RESOURCE_VIEW_DESC const chrominancePlaneDesc = CD3D11_SHADER_RESOURCE_VIEW_DESC(
pTexture,
D3D11_SRV_DIMENSION_TEXTURE2D,
DXGI_FORMAT_R8G8_UNORM
);
ID3D11ShaderResourceView* m_chrominanceView = NULL;
err = pd3dDevice->CreateShaderResourceView(pTexture,
&chrominancePlaneDesc, &m_chrominanceView);
}
if (FAILED(err))
{
fprintf(stderr, "Error creating texture\n");
exit(1);
}
return pTexture;
Creating D3D11 device:
ID3D11Device* dev11 = NULL;
ID3D11DeviceContext* devcon11 = NULL;
D3D_FEATURE_LEVEL featureLevels[]{
D3D_FEATURE_LEVEL_11_1,
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
D3D_FEATURE_LEVEL_9_3,
D3D_FEATURE_LEVEL_9_2,
D3D_FEATURE_LEVEL_9_1
};
int err = D3D11CreateDevice(
nullptr,
D3D_DRIVER_TYPE_HARDWARE,
nullptr,
D3D11_CREATE_DEVICE_VIDEO_SUPPORT,
featureLevels, sizeof(featureLevels) / sizeof(D3D_FEATURE_LEVEL),
D3D11_SDK_VERSION,
&dev11,
nullptr,
&devcon11);
return dev11;
Encoding:
auto status = 0;
status = avcodec_send_frame(ctx, frame); //error happening here
AVPacket* pkt;
pkt = av_packet_alloc();
if (status < 0) {
fprintf(stderr, "Error sending a frame for encoding\n");
exit(1);
}
while (status >= 0) {
status = avcodec_receive_packet(ctx, pkt);
if (status == AVERROR(EAGAIN) || status == AVERROR_EOF)
return;
else if (status < 0) {
fprintf(stderr, "Error during encoding\n");
exit(1);
}
printf("Write packet \n", pkt->pts, pkt->size);
fwrite(pkt->data, 1, pkt->size, outfile);
av_packet_unref(pkt);
}
Everything runs well until encoding the frame. I have tried sending a dummy nv12 data (not a d3d11 texture) and it works well.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
