You (and yours truly, actually) should probably study deeply http://dranger.com/ffmpeg/tutorial05.html. Anyway, what does ffprobe say about your output.mpg file? Does it recognize the frame rate? IIRC it will not know duration for this format.
Alex On Fri, Jun 10, 2011 at 9:24 PM, Jiří Novák <[email protected]> wrote: > Thank you Alex! > > couldn't you please show me how? I am absolute begginer with libavcodec and > with the lack of documentation and version differences I am more fighting > than enjoying with this library... :( > > Jiri > > On 06/10/2011 03:22 PM, Alex Cohn wrote: >> >> You should set pts and maybe duration for pFrameYUV before you feed it >> into video encoder. >> >> Alex >> >> On Friday, June 10, 2011, Jiří Novák<[email protected]> wrote: >>> >>> Hello, >>> >>> I am trying to capture the X11 screen (using "x11grab") to the mpg output >>> format. This is first step (afterward i will need to add alsa audio), join >>> it into conteiner and at some point send it by socket. >>> >>> The problem I have is, that the mpg video I received is not syncronized, >>> in other words it looses its timing and is reproduced all in 2 seconds :(. >>> >>> Could anybody with experience of this please help me to correct this >>> issue in my code? >>> >>> Thank you very much, >>> Jiri Novak >>> >>> >>> /*==========================================================================================================*/ >>> #include<iostream> >>> #include<stdio.h> >>> #include<assert.h> >>> #include<fstream> >>> >>> extern "C" { >>> #ifndef INT64_C >>> #define INT64_C(c) (c ## LL) >>> #define UINT64_C(c) (c ## ULL) >>> #endif >>> #include<libavcodec/avcodec.h> >>> #include<libswscale/swscale.h> >>> #include<libavformat/avformat.h> >>> #include<libavdevice/avdevice.h> >>> #include<libavfilter/avfilter.h> >>> } >>> >>> int main(int argc, char *argv[]) { >>> // register devices, filters and codecs >>> avdevice_register_all(); >>> avfilter_register_all(); >>> avcodec_init(); >>> avcodec_register_all(); >>> av_register_all(); >>> >>> // file format, format context >>> AVInputFormat *pInputFormat = av_find_input_format("x11grab"); >>> AVFormatContext *pFormatCtx = avformat_alloc_context(); >>> assert(pInputFormat != NULL&& "format unrecognized - pInputFormat is >>> NULL!"); >>> assert(pFormatCtx != NULL&& "format context could not be allocated - >>> pFormatCtx pointer is NULL!"); >>> >>> // format parameters >>> AVFormatParameters input_video_parameters, *ivp >>> =&input_video_parameters; >>> memset(ivp, 0, sizeof(*ivp)); >>> ivp->prealloced_context = 1; >>> ivp->time_base= (AVRational){1,25}; >>> ivp->width = 1400; >>> ivp->height = 1050; >>> >>> // input_format_context, filename, input_format, buffer_size, >>> format_parameters >>> int ret = av_open_input_file(&pFormatCtx, ":0.0", pInputFormat, 0, >>> ivp); >>> assert(ret>= 0&& "input video file could not be opened!"); >>> >>> // retrieve stream information >>> ret = av_find_stream_info(pFormatCtx); >>> assert(pFormatCtx>= 0&& "could not retrieve input video stream >>> info!"); >>> >>> // dump information >>> dump_format(pFormatCtx, 0, ":0.0", 0); >>> >>> // find the first video stream >>> int videoStream=-1; >>> for(int i=0; i<pFormatCtx->nb_streams; i++) >>> if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO) { >>> videoStream=i; >>> break; >>> } >>> if(videoStream==-1) >>> return -1; // Didn't find a video stream >>> >>> // get a pointer to the codec context for the video stream >>> AVCodecContext *pCodecCtxDec = pFormatCtx->streams[videoStream]->codec; >>> >>> // find the decoder for the video stream >>> AVCodec *pCodecDec = avcodec_find_decoder(pCodecCtxDec->codec_id); >>> if(pCodecDec==NULL) { >>> fprintf(stderr, "Unsupported codec!\n"); >>> return -1; // Codec not found >>> } >>> >>> // open codec >>> if (avcodec_open(pCodecCtxDec, pCodecDec)<0) >>> return -1; // Could not open codec >>> >>> // alocate codec context >>> AVCodecContext *pCodecCtxEnc = avcodec_alloc_context(); >>> assert(pCodecCtxEnc != NULL&& "pCodecCtxEnc pointer is null!"); >>> >>> // put sample parameters >>> pCodecCtxEnc->bit_rate = 400000; >>> pCodecCtxEnc->width = 1400; >>> pCodecCtxEnc->height = 1050; >>> pCodecCtxEnc->time_base= (AVRational){1,25}; >>> pCodecCtxEnc->gop_size = 10; >>> pCodecCtxEnc->max_b_frames=1; >>> pCodecCtxEnc->pix_fmt = PIX_FMT_YUV420P; >>> >>> // find MPEG4 encoder >>> AVCodec *pCodecEnc = avcodec_find_encoder(CODEC_ID_MPEG2VIDEO); >>> assert(pCodecEnc != NULL&& "pCodecEnc pointer is null!"); >>> >>> // open the codec >>> int retval = avcodec_open(pCodecCtxEnc, pCodecEnc); >>> assert(retval == 0&& "could not open codec!"); >>> >>> // allocate video frame >>> AVFrame *pFrame = avcodec_alloc_frame(); >>> >>> // allocate an AVFrame structure >>> AVFrame *pFrameYUV=avcodec_alloc_frame(); >>> if(pFrameYUV==NULL) >>> return -1; >>> >>> // calculate the bytes needed for the output image and create buffer >>> for the output image >>> int nbytes = avpicture_get_size(PIX_FMT_YUV420P, pCodecCtxEnc->width, >>> pCodecCtxEnc->height); >>> uint8_t* outbuffer = (uint8_t*)av_malloc(nbytes*10); >>> >>> // assign appropriate parts of buffer to image planes in pFrameYUV >>> avpicture_fill((AVPicture *)pFrameYUV, outbuffer, PIX_FMT_YUV420P, >>> pCodecCtxDec->width, pCodecCtxDec->height); >>> >>> int frameFinished; >>> AVPacket packet; >>> >>> int i=0; >>> struct SwsContext *img_convert_ctx = NULL; >>> >>> FILE *f = fopen("output.mpg", "wb"); >>> int out_size; >>> >>> while (av_read_frame(pFormatCtx,&packet)>=0&& i<50) { >>> fflush(stdout); >>> >>> // is this a packet from the video stream >>> if(packet.stream_index==videoStream) { >>> // Decode video frame >>> avcodec_decode_video2(pCodecCtxDec, pFrame,&frameFinished,&packet); >>> >>> // Did we get a video frame? >>> if(frameFinished) { >>> if (img_convert_ctx == NULL) { >>> img_convert_ctx = sws_getContext(pCodecCtxDec->width, >>> pCodecCtxDec->height, PIX_FMT_BGRA, pCodecCtxEnc->width, >>> pCodecCtxEnc->height, PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL); >>> >>> if (img_convert_ctx == NULL) >>> std::cerr<< "Error"<< std::endl; >>> } >>> sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, >>> pCodecCtxEnc->height, pFrameYUV->data, pFrameYUV->linesize); >>> >>> out_size = avcodec_encode_video(pCodecCtxEnc, outbuffer, nbytes, >>> pFrameYUV); >>> //printf("write frame %3d (size=%5d)\n", i, out_size); >>> fwrite(outbuffer, 1, out_size, f); >>> } >>> } >>> >>> // Free the packet that was allocated by av_read_frame >>> av_free_packet(&packet); >>> i++; >>> } >>> >>> //get the delayed frames >>> for(; out_size; i++) { >>> fflush(stdout); >>> out_size = avcodec_encode_video(pCodecCtxEnc, outbuffer, nbytes, >>> NULL); >>> //printf("write frame %3d (size=%5d)\n", i, out_size); >>> fwrite(outbuffer, 1, out_size, f); >>> } >>> >>> // add sequence end code to have a real mpeg file >>> outbuffer[0] = 0x00; >>> outbuffer[1] = 0x00; >>> outbuffer[2] = 0x01; >>> outbuffer[3] = 0xb7; >>> fwrite(outbuffer, 1, 4, f); >>> fclose(f); >>> >>> return 0; >>> } >>> >>> >> _______________________________________________ >> Libav-user mailing list >> [email protected] >> http://ffmpeg.org/mailman/listinfo/libav-user > > _______________________________________________ > Libav-user mailing list > [email protected] > http://ffmpeg.org/mailman/listinfo/libav-user > _______________________________________________ Libav-user mailing list [email protected] http://ffmpeg.org/mailman/listinfo/libav-user
