h.264 - Why there is no AVFrame->data[2] data when decode h264 by ffmpeg use "h264_cuvid" -
env: ubuntu 16.04 64 bit; ffmpeg 3.3.2 build whih cuda cuvid libnpp...
use ffmpeg cmd: ffmpeg -vsync 0 -c:v h264_cuvid -i test.264 -f rawvideo test.yuv works fine, generated yuv file ok.
but when decode 264 file code use 'h264_cuvid' decoder, problem happens, code:
#include <stdio.h> #define __stdc_constant_macros #ifdef _win32 //windows extern "c" { #include "libavcodec/avcodec.h" }; #else //linux... #ifdef __cplusplus extern "c" { #endif #include <libavcodec/avcodec.h> #ifdef __cplusplus }; #endif #endif //test different codec #define test_h264 1 #define test_hevc 0 int main(int argc, char* argv[]) { avcodec *pcodec; avcodeccontext *pcodecctx= null; avcodecparsercontext *pcodecparserctx=null; file *fp_in; file *fp_out; avframe *pframe; const int in_buffer_size=4096; unsigned char in_buffer[in_buffer_size + ff_input_buffer_padding_size]= {0}; unsigned char *cur_ptr; int cur_size; avpacket packet; int ret, got_picture; #if test_hevc enum avcodecid codec_id=av_codec_id_hevc; char filepath_in[]="bigbuckbunny_480x272.hevc"; #elif test_h264 avcodecid codec_id=av_codec_id_h264; char filepath_in[]="2_60_265to264.264"; #else avcodecid codec_id=av_codec_id_mpeg2video; char filepath_in[]="bigbuckbunny_480x272.m2v"; #endif char filepath_out[]="mainsend.yuv"; int first_time=1; //av_log_set_level(av_log_debug); avcodec_register_all(); // pcodec = avcodec_find_decoder(codec_id); pcodec = avcodec_find_decoder_by_name("h264_cuvid"); if (!pcodec) { printf("codec not found\n"); return -1; } pcodecctx = avcodec_alloc_context3(pcodec); if (!pcodecctx) { printf("could not allocate video codec context\n"); return -1; } pcodecparserctx=av_parser_init(pcodec->id); if (!pcodecparserctx) { printf("could not allocate video parser context\n"); return -1; } if (avcodec_open2(pcodecctx, pcodec, null) < 0) { printf("could not open codec\n"); return -1; } //input file fp_in = fopen(filepath_in, "rb"); if (!fp_in) { printf("could not open input stream\n"); return -1; } //output file fp_out = fopen(filepath_out, "wb"); if (!fp_out) { printf("could not open output yuv file\n"); return -1; } pframe = av_frame_alloc(); av_init_packet(&packet); while (1) { cur_size = fread(in_buffer, 1, in_buffer_size, fp_in); if (cur_size == 0) break; cur_ptr=in_buffer; while (cur_size>0) { int len = av_parser_parse2( pcodecparserctx, pcodecctx, &packet.data, &packet.size, cur_ptr, cur_size, av_nopts_value, av_nopts_value, av_nopts_value); cur_ptr += len; cur_size -= len; if(packet.size==0) continue; //some info avcodecparsercontext printf("[packet]size:%6d\t",packet.size); switch(pcodecparserctx->pict_type) { case av_picture_type_i: printf("type:i\tnumber:%4d\n",pcodecparserctx->output_picture_number); break; case av_picture_type_p: printf("type:p\t"); break; case av_picture_type_b: printf("type:b\t"); break; default: printf("type:other\t"); break; } printf("number:%4d\n",pcodecparserctx->output_picture_number); avframe* myframe = av_frame_alloc(); ret = avcodec_decode_video2(pcodecctx, myframe, &got_picture, &packet); if (ret < 0) { printf("decode error.\n"); return ret; } if (got_picture) { if(first_time) { printf("\ncodec full name:%s\n",pcodecctx->codec->long_name); printf("width:%d\nheight:%d\n\n",pcodecctx->width,pcodecctx->height); first_time=0; } //y, u, v for(int i=0; i<myframe->height; i++) { fwrite(myframe->data[0]+myframe->linesize[0]*i,1,myframe->width,fp_out); } for(int i=0; i<myframe->height/2; i++) { fwrite(myframe->data[1]+myframe->linesize[1]*i,1,myframe->width/2,fp_out); } for(int i=0; i<myframe->height/2; i++) { fwrite(myframe->data[2]+myframe->linesize[2]*i,1,myframe->width/2,fp_out); } // printf("pframe's width height %d %d\t key frame %d\n",myframe->width,myframe->height,myframe->key_frame); printf("succeed decode 1 frame!\n"); av_frame_free(&myframe); } } } fclose(fp_in); fclose(fp_out); av_parser_close(pcodecparserctx); av_frame_free(&pframe); avcodec_close(pcodecctx); av_free(pcodecctx); return 0; } in demo code, call h264_cuvid vcodec_find_decoder_by_name("h264_cuvid"); code crash @ fwrite(myframe->data[2]+myframe->linesize[2]*i,1,myframe->width/2,fp_out);
after debug codeblocks, found there no data in myframe->data[2] codeblocks watching window
any suggestion? thanks!
"h264" decoder's frame pix format av_pix_fmt_yuv420p
"h264_cuvid" decoder's frame pix format av_pix_fmt_nv12
so, edit code
for(int i=0; i<myframe->height; i++) { fwrite(myframe->data[0]+myframe->linesize[0]*i,1,myframe->width,fp_out); } for(int i=0; i<myframe->height/2; i++) { fwrite(myframe->data[1]+myframe->linesize[1]*i,1,myframe->width,fp_out); } works fine
Comments
Post a Comment