[Libav-user] FFMpeg - x264
Denis
info at denisgottardello.it
Tue Sep 13 12:22:03 CEST 2011
Like you can see below I have write a function for grab frames from webcam and
for store these in a mpg file with h264.
I am sure that this function IS NOT CORRECT! I can see the video (if you want
to try "www.denisgottardello.it/a.mpg") with mplayer but mplayer shows the
video at 50 fps. The function has 25 fps instead.
Vlc does not work.
Wich is the error? I can not to find it. I can not understand wich is the right
way for store a frame in a h264 file.
Can you help me? I'm disperate!
void QThCamera::run() {
qDebug() << "QThCamera::run() start";
QString fileName= "a.mpg";
CvCapture *Capture= NULL;
Capture= cvCreateCameraCapture(Index, Width, Height);
if (!Capture) qDebug() << "Cannot open or initialize webcam!";
else {
if (ExternalFrame) cvNamedWindow("Frame", CV_WINDOW_AUTOSIZE);
IplImage *frame= 0;
CvFont font;
cvInitFont(&font, CV_FONT_HERSHEY_SIMPLEX, 0.5f, 0.5f);
AVOutputFormat *pOutputFormat;
pOutputFormat= av_guess_format("h264", NULL, NULL);
if (!pOutputFormat) {
qDebug() << "Could not set output format, using MPEG.";
pOutputFormat= av_guess_format("mp4", NULL, NULL);
}
if (!pOutputFormat) qDebug() << "Could not set output format.";
else {
AVFormatContext *pFormatCtx= avformat_alloc_context();
if (!pFormatCtx) qDebug() << "avformat_alloc_context Error!";
else {
pFormatCtx->oformat= pOutputFormat;
snprintf(pFormatCtx->filename, sizeof(pFormatCtx->filename),
"%s", fileName.toStdString().c_str());
AVStream *pVideoStream= av_new_stream(pFormatCtx,0);
if (!pVideoStream) qDebug() << "av_new_stream Error!";
else {
AVCodecContext *pCodecCtx= pVideoStream->codec;
pCodecCtx->codec_id= pOutputFormat->video_codec;
pCodecCtx->codec_type= AVMEDIA_TYPE_VIDEO;
pCodecCtx->bit_rate= 40000;
pCodecCtx->width= Width;
pCodecCtx->height= Height;
pCodecCtx->time_base.den= 25;
pCodecCtx->time_base.num= 1;
pCodecCtx->gop_size= 25;
pCodecCtx->pix_fmt= PIX_FMT_YUV420P;
avcodec_thread_init(pCodecCtx, 10);
if (pFormatCtx->oformat->flags & AVFMT_GLOBALHEADER)
pCodecCtx->flags |= CODEC_FLAG_GLOBAL_HEADER;
if (av_set_parameters(pFormatCtx, NULL)< 0) qDebug() <<
"av_set_parameters Error!";
else {
dump_format(pFormatCtx, 0,
fileName.toStdString().c_str(), 1);
AVCodec *pCodec= avcodec_find_encoder(pCodecCtx-
>codec_id);
if (!pCodec) qDebug() << "avcodec_find_encoder Error!";
else {
if (avcodec_open(pCodecCtx, pCodec)< 0) qDebug()
<< "avcodec_open Error!";
else {
if (url_fopen(&pFormatCtx->pb,
fileName.toStdString().c_str(), URL_WRONLY)< 0) qDebug() << "url_fopen Error!";
else {
av_write_header(pFormatCtx);
int BYTEPIC= Width * Height * 3;
uint8_t *pOutBuffer=
(uint8_t*)malloc(BYTEPIC); {
int Frames= 0;
QDateTime QDTStart=
QDateTime::currentDateTime();
while (DoStart) {
if (!cvSetChannel(Capture,
Channel)) qDebug() << "Unable to set channel.";
frame= cvQueryFrame(Capture);
if (frame) {
if (MainForm->ui-
>QCBAutoBrightness->isChecked()) {
int Brightness=
BrightnessOfAPixel(frame);
Brightness= ((Brightness *
200 / 256) - 100) * -1;
IplImage *frame2=
ContrastBrightness(frame, 0, Brightness); {
cvCopyImage(frame2,
frame);
}{
cvReleaseImage(&frame2);
}
} else {
IplImage *frame2=
ContrastBrightness(frame, MainForm->ui->QHSContrast->value(), MainForm->ui-
>QHSBrightness->value()); {
cvCopyImage(frame2,
frame);
}{
cvReleaseImage(&frame2);
}
}
if (MainForm->ui-
>QCBShowDateTime->isChecked()) cvPutText(frame,
QDateTime::currentDateTime().toString("dd-MM-yyyy hh:mm:ss").toAscii(),
cvPoint(10, 20), &font, cvScalar(255, 255, 255));
if (MainForm->ui->QRBRotate90-
>isChecked()) {
IplImage *frame2=
Rotate(frame, 90); {
cvCopyImage(frame2,
frame);
}{
cvReleaseImage(&frame2);
}
} else if (MainForm->ui-
>QRBRotate180->isChecked()) {
IplImage *frame2=
Rotate(frame, 180); {
cvCopyImage(frame2,
frame);
}{
cvReleaseImage(&frame2);
}
} else if (MainForm->ui-
>QRBRotate270->isChecked()) {
IplImage *frame2=
Rotate(frame, 270); {
cvCopyImage(frame2,
frame);
}{
cvReleaseImage(&frame2);
}
}
if (ExternalFrame)
cvShowImage("Frame", frame);
QImage Image(frame->width,
frame->height, QImage::Format_RGB888);
const unsigned char *data=
NULL;
data= (unsigned char*)(frame-
>imageData);
Image= QImage(data, frame-
>width, frame->height, frame->widthStep, QImage::Format_RGB888);
if (DoStart) emit
SendNewImage(Image);
AVFrame *pAVFrame=
avcodec_alloc_frame();
uint8_t *pBuffer=
(uint8_t*)malloc(avpicture_get_size(PIX_FMT_YUV420P, Width, Height)); {
avpicture_fill((AVPicture*)pAVFrame,
pBuffer, PIX_FMT_YUV420P, Width, Height);
IplImageToAVFrame(frame,
pAVFrame, Width, Height, PIX_FMT_YUV420P);
pAVFrame->pts= Frames;
int OutSize=
avcodec_encode_video(pCodecCtx, pOutBuffer, BYTEPIC, pAVFrame);
if (OutSize> 0) {
AVPacket Packet;
av_init_packet(&Packet);
//pkt.pts=
av_rescale_q(pCodecCtx->coded_frame->pts, pCodecCtx->time_base, pVideoStream-
>time_base);
//if (pCodecCtx-
>coded_frame->key_frame) pkt.flags |= AV_PKT_FLAG_KEY;
Packet.stream_index=
pVideoStream->index;
Packet.data=
pOutBuffer;
Packet.size= OutSize;
if
(av_write_frame(pFormatCtx, &Packet)!= 0) qDebug() << "av_write_frame Error!";
}
Frames++;
if (Frames> pCodecCtx-
>time_base.den / pCodecCtx->time_base.num * 20) break;
}{
av_free(pAVFrame);
free(pBuffer);
}
} else qDebug() <<
"QThCamera::run() frame= false";
}
qDebug() << Frames /
QDTStart.secsTo(QDateTime::currentDateTime());
}{
free(pOutBuffer);
}
av_write_trailer(pFormatCtx);
url_fclose(pFormatCtx->pb);
}
avcodec_close(pVideoStream->codec);
}
}
for (int count= 0; count< pFormatCtx->nb_streams;
count++) {
av_freep(&pFormatCtx->streams[count]->codec);
av_freep(&pFormatCtx->streams[count]);
}
}
}
av_free(pFormatCtx);
}
}
cvReleaseCapture(&Capture);
if (ExternalFrame) cvDestroyWindow("Frame");
}
qDebug() << "QThCamera::run() stop";
}
--
www.denisgottardello.it
Skype: mrdebug
Videosurveillance and home automation!
http://www.denisgottardello.it/DomusBoss/DomusBossIndice.php
More information about the Libav-user
mailing list