打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
将摄像头原始RGB数据流编码成H.264文件

extern "C"{#include "avcodec.h"#include "avformat.h"#include "avio.h"#include "avutil.h"#include "common.h"#include "intfloat_readwrite.h"#include "inttypes.h"#include "log.h"#include "mathematics.h"#include "mem.h"#include "rational.h"#include "stdint.h"#include "swscale.h"}#pragma comment(lib,"avcodec.lib")#pragma comment(lib,"avformat.lib")#pragma comment(lib,"avutil.lib")#define RGBTOYUV(B, G, R, Y, U, V) \Y = ( ( 66 * R   129 * G   25 * B   128) >> 8)   16;U = ( ( -38 * R - 74 * G   112 * B   128) >> 8)   128;V = ( ( 112 * R - 94 * G - 18 * B   128) >> 8)   128;size_t BufSize = 9437184;BYTE *pStream = new BYTE[BufSize];BYTE* pBmp24;int CALLBACK SnapThreadCallback(BYTE *pBuffer) //摄像头显示回调函数{pBmp24 = CameraISP(pBuffer);if(pBmp24){if (bVideo){memcpy(pStream, pBmp24, BufSize);}CameraDisplayRGB24(pBmp24);}return TRUE;}void CXXDlg::OnBtnVideo() {    // TODO: Add your control notification handler code here    //CWinThread *pVedioStart;    if (m_VideoMode != VIDEOMODE_PLAY)    {        GetDlgItem(IDC_BTN_VIDEO)->SetWindowText("停止录像");            AfxBeginThread((AFX_THREADPROC)VIDEO, this, THREAD_PRIORITY_ABOVE_NORMAL, 0, NULL);        m_VideoMode = VIDEOMODE_PLAY;            }    else    {        m_VideoMode = VIDEOMODE_STOP;        GetDlgItem(IDC_BTN_VIDEO)->SetWindowText("开始录像");            }}UINT VIDEO(LPVOID pParam){    CXXDlg * dlg = (CXXDlg *)pParam;    BYTE* yuv = new BYTE[bufzise * 3 / 2];    CString svideofile;     CTime time = CTime::GetCurrentTime();    svideofile.Format("%02d%02d%02d%02d%02d", time.GetMonth(), time.GetDay(),         time.GetHour(), time.GetMinute(), time.GetSecond());    CFile file(svideofile, CFile::modeWrite|CFile::modeCreate);    int m_frame_count = 0;    Sleep(100);    bVideo = TRUE;    while(dlg->m_VideoMode != VIDEOMODE_STOP)    {        if (StreamOK)        {            dlg->RGB2YUV(&pStream, &yuv, 3, ImgW, ImgH);            memset(lpCurrentImage, 0, bufzise * 3);            file.SeekToEnd();            file.Write(yuv, bufzise*3/2);            m_frame_count  ;        }            }    file.Close();    dlg->SaveToH264(svideofile, ImgW, ImgH, m_frame_count);    AfxMessageBox("录像已保存!");        return 0;}void CXXDlg::RGB2YUV(BYTE** rgb, BYTE** yuv, unsigned rgbIncrement, int nWidth, int nHeight){    unsigned width    = nWidth;  // 图像宽度    unsigned height    = nHeight; // 图像高度        const unsigned planeSize = width*height;    const unsigned halfWidth = width >> 1;    unsigned count = 0;    BYTE * yplane  = *yuv;    BYTE * uplane  = *yuv   planeSize;    BYTE * vplane  = *yuv   planeSize   (planeSize >> 2);    BYTE * rgbIndex = *rgb;        for (unsigned y = 0; y < height; y  )     {        BYTE * yline  = yplane   (y * width);        BYTE * uline  = uplane   ((y >> 1) * halfWidth);        BYTE * vline  = vplane   ((y >> 1) * halfWidth);                        rgbIndex = *rgb   (width*(height-1-y)*rgbIncrement); //将图像翻转        for (unsigned x = 0; x < width; x =2)         {            RGBTOYUV(rgbIndex[0], rgbIndex[1], rgbIndex[2], *yline, *uline, *vline);                        rgbIndex  = rgbIncrement; count  ;            yline  ;            RGBTOYUV(rgbIndex[0], rgbIndex[1], rgbIndex[2],*yline, *uline, *vline);            rgbIndex  = rgbIncrement; count  ;            yline  ;            uline  ;            vline  ;        }    }}BOOL CXXDlg::SaveToH264 (CString YUVfile, int vWidth, int vHeight, int count){    AVFormatContext* oc;    AVOutputFormat* fmt;    AVStream* video_st;    double video_pts;    uint8_t* video_outbuf;    uint8_t* picture_buf;    AVFrame* picture;    int size;    int ret;    int video_outbuf_size;        CString s;    s = YUVfile   ".avi";    const char *videofile = s.GetBuffer(0);    s.ReleaseBuffer();    FILE *fin = fopen(YUVfile, "rb");        CFile::modeWrite|CFile::modeCreate);    av_register_all();    fmt = guess_format(NULL, videofile, NULL);    oc = av_alloc_format_context();    oc->oformat = fmt;    snprintf(oc->filename, sizeof(oc->filename), "%s", videofile);    video_st = NULL;    if (fmt->video_codec != CODEC_ID_NONE)    {        AVCodecContext* c;        video_st = av_new_stream(oc, 0);        c = video_st->codec;        c->codec_id = fmt->video_codec;        c->codec_type = CODEC_TYPE_VIDEO;        c->bit_rate = 400000;        c->width = vWidth;        c->height = vHeight;        c->time_base.num = 1;        c->time_base.den = 10;        c->gop_size = 12;        c->pix_fmt = PIX_FMT_YUV420P;        if (c->codec_id == CODEC_ID_MPEG2VIDEO)        {            c->max_b_frames = 2;        }        if (c->codec_id == CODEC_ID_MPEG1VIDEO)        {            c->mb_decision = 2;        }        if (!strcmp(oc->oformat->name, "mp4") || !strcmp(oc->oformat->name, "mov") || !strcmp(oc->oformat->name, "3gp"))        {            c->flags |= CODEC_FLAG_GLOBAL_HEADER;        }    }    if (av_set_parameters(oc, NULL)<0)    {        return FALSE;    }        dump_format(oc, 0, videofile, 1);    if (video_st)    {        AVCodecContext* c;        AVCodec* codec;        c = video_st->codec;        codec = avcodec_find_encoder(c->codec_id);        if (!codec)        {            return FALSE;        }        if (avcodec_open(c, codec) < 0)        {            return FALSE;        }        if (!(oc->oformat->flags & AVFMT_RAWPICTURE))        {            video_outbuf_size = 200000;            video_outbuf = (uint8_t*)av_malloc(video_outbuf_size);        }        picture = avcodec_alloc_frame();        size = avpicture_get_size(c->pix_fmt, c->width, c->height);        picture_buf = (uint8_t*)av_malloc(size);        if (!picture_buf)        {            av_free(picture);        }        avpicture_fill((AVPicture*)picture, picture_buf, c->pix_fmt, c->width, c->height);    }    if (!(fmt->flags & AVFMT_NOFILE))    {        if (url_fopen(&oc->pb, videofile, URL_WRONLY) < 0)        {            return FALSE;        }    }    av_write_header(oc);    for (int i=0; i<count; i  )    {        if (savedlg)        {            savedlg->PostMessage(WM_COUNT, NULL, (LPARAM)i);        }            if (video_st)        {            video_pts = (double)(video_st->pts.val * video_st->time_base.num / video_st->time_base.den);        }        else        {            video_pts = 0.0;        }        if (!video_st/* || video_pts >= 5.0*/)        {            break;        }        AVCodecContext* c;        c = video_st->codec;        size = c->width * c->height;        if (fread(picture_buf, 1, size*3/2, fin) < 0)        {            break;        }                picture->data[0] = picture_buf;  // 亮度        picture->data[1] = picture_buf  size;  // 色度         picture->data[2] = picture_buf  size*5/4; // 色度         if (oc->oformat->flags & AVFMT_RAWPICTURE)        {            AVPacket pkt;            av_init_packet(&pkt);            pkt.flags |= PKT_FLAG_KEY;            pkt.stream_index = video_st->index;            pkt.data = (uint8_t*)picture;            pkt.size = sizeof(AVPicture);            ret = av_write_frame(oc, &pkt);        }        else        {            int out_size = avcodec_encode_video(c, video_outbuf, video_outbuf_size, picture);            if (out_size > 0)            {                AVPacket pkt;                av_init_packet(&pkt);                pkt.pts = av_rescale_q(c->coded_frame->pts, c->time_base, video_st->time_base);                if (c->coded_frame->key_frame)                {                    pkt.flags |= PKT_FLAG_KEY;                }                pkt.stream_index = video_st->index;                pkt.data = video_outbuf;                pkt.size = out_size;                        ret = av_write_frame(oc, &pkt);            }        }    }    if (video_st)    {        avcodec_close(video_st->codec);        av_free(picture);        av_free(video_outbuf);    }    av_write_trailer(oc);    for (int j=0; j<oc->nb_streams; j  )    {        av_freep(&oc->streams[j]->codec);        av_freep(&oc->streams[j]);    }    if (!(fmt->flags & AVFMT_NOFILE))    {        url_fclose(oc->pb);    }    av_free(oc);    fclose(fin);    DeleteFile(YUVfile);    //AfxMessageBox("视频已保存!");        return TRUE;}

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
FFMpeg 中比较重要的函数以及数据结构
FFmpeg浅尝辄止(二)
FFMpeg写MP4文件例子分析
使用ffmpeg进行h.264编码
Android Bitmap和YUV之间的相互转换
rgb
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服