c - Forcing global headers in LibAV -
i'm trying write c program using libav takes input video webcam , saves h264 mp4 file. i'm modifying working program saves .ppm frames webcam. i'm unable convert avpackets may written, though--specifically, avformat_write_header() failing, messages
[mp4 @ 0050c000] codec stream 0 not use global headers container format requires global headers [mp4 @ 0050c000] not find tag codec none in stream #0, codec not supported in container the call apparently returning error -22, can find no place error code explained. how can force avformat_write_header() add in global headers when it's trying write mp4? code below; of adapted this question, i'm trying adapt input video file webcam.
int _tmain(int argc, _tchar* argv[]) { avinputformat *inputformat = null; avdictionary *inputdictionary= null; avformatcontext *inputformatctx = null; avformatcontext *outputformatctx = null; avcodeccontext *inputcodecctxorig = null; avcodeccontext *inputcodecctx = null; avcodeccontext *outputcodecctx; avcodec *inputcodec = null; avcodec *outputcodec = null; avstream *stream = null; aviocontext *aviocontext = null; avcodec_register_all(); av_register_all(); avdevice_register_all(); av_dict_set(&inputdictionary, "logitech hd pro webcam c920", "video", 0); avformat_alloc_output_context2(&outputformatctx, null, null, "output.mp4"); avio_open(&aviocontext, "output.mp4", avio_flag_write); outputformatctx->pb = aviocontext; stream = avformat_new_stream(outputformatctx, outputcodec); inputformat = av_find_input_format("dshow"); int r = avformat_open_input(&inputformatctx, "video=logitech hd pro webcam c920", inputformat, &inputdictionary); if (r != 0) { fprintf(stderr, "avformat_open_input() failed error %d!\n", r); return -1; } r = avformat_find_stream_info(inputformatctx, null); if (r != 0) { fprintf(stderr, "avformat_find_stream_info() failed!\n"); return -1; } av_dump_format(inputformatctx, 0, "video=logitech hd pro webcam c920", 0); unsigned int i; int videostream; videostream = -1; (i = 0; < inputformatctx->nb_streams; i++) { if (inputformatctx->streams[i]->codec->codec_type == avmedia_type_video { videostream = i; break; } } if (videostream == -1) { return -1; } inputcodecctxorig = inputformatctx->streams[videostream]->codec; inputcodec = avcodec_find_decoder(inputcodecctxorig->codec_id); if (inputcodec == null) { fprintf(stderr, "avcodec_find_decoder() failed!\n"); return -1; } else { printf("supported codec!\n"); } inputcodecctx = avcodec_alloc_context3(inputcodec); if (inputcodecctx == null) { fprintf(stderr, "avcodec_alloc_context3() failed!\n"); return -1; } if (avcodec_copy_context(inputcodecctx, inputcodecctxorig) != 0) { fprintf(stderr, "avcodec_copy_context() failed!\n"); return -1; } if (avcodec_open2(inputcodecctx,inputcodec,&inputdictionary) < 0) { fprintf(stderr, "avcodec_open2() failed!\n"); return -1; } outputformatctx->oformat = av_guess_format(null, "output.mp4", null); outputformatctx->oformat->flags |= avfmt_globalheader; outputcodecctx = avcodec_alloc_context3(outputcodec); avcodec_copy_context(outputcodecctx, inputcodecctx); outputcodec = inputcodec; avcodec_open2(outputcodecctx, outputcodec, null); avpacket packet; printf("foo\n"); int errnum = avformat_write_header(outputformatctx, &inputdictionary); printf("bar %d\n", errnum); while(av_read_frame(inputformatctx, &packet)>=0) { av_interleaved_write_frame(outputformatctx, &packet); av_free_packet(&packet); } avcodec_close(inputcodecctx); avcodec_close(inputcodecctxorig); avformat_close_input(&inputformatctx); return 0; }
how can force avformat_write_header() add in global headers
global headers written encoder, later muxer reads them codec's extra_data field. should set flag in codec's context, before call avcodec_open2().
outputcodecctx->flags |= av_codec_flag_global_header; [mp4 @ 0050c000] not find tag codec none in stream #0, codec not supported in container
you can try setup encoder explicitly (i.e. manually), or copy codeccontext original input codeccontext.
outputcodec = av_codec_find_encoder(av_codec_id_h264); if(!outputcodec) return -1; //no encoder found outputcodecctx = avcodec_alloc_context3(outputcodec); avcodec_copy_context(outputcodecctx, inputcodecctxorig); //copy orig //you have make sure each field populated correctly //with debugger or assertations assert(outputcodecctx->codec_id == av_codec_id_h264); //etc outputcodecctx->flags |= av_codec_flag_global_header; if(avcodec_open2(outputcodecctx, outputcodec, null) <0) return -1;
Comments
Post a Comment