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

Reply via email to