智能指针处理---bo

摘要:
//cpp:定义控制台应用程序的入口点。
//sdltest1.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"#include <stdio.h>#include <stdlib.h>
extern "C"{
    #include <SDL.h>#include "libavutil/opt.h"#include "libavutil/channel_layout.h"#include "libavutil/common.h"#include "libavutil/imgutils.h"#include "libavutil/mathematics.h"#include "libavutil/samplefmt.h"#include "libavutil/time.h"#include "libavutil/fifo.h"#include "libavcodec/avcodec.h"#include "libavformat/avformat.h"#include "libavformat/avio.h"#include "libavfilter/avfiltergraph.h"#include "libavfilter/avfilter.h"#include "libavfilter/buffersink.h"#include "libavfilter/buffersrc.h"#include "libswscale/swscale.h"#include "libswresample/swresample.h"}
#include <memory>#include <vector>#include <windows.h>#include <thread>#include <mutex>#include <queue>#include <iostream>#include "sdlplayer.h"

#pragma comment(lib, "avcodec.lib")

bool saveAsBitmap(AVFrame *pFrameRGB, int width, int height, intiFrame);


//int mymain();
//extern "C" _declspec(dllexport) int mymain();
int mymain(char*file);
//int _tmain(int argc, _TCHAR* argv[])
int main(int argc, char*argv[])
{
    printf("come this -->
");
    if(argc!=2) {
        printf("Args count not right!
");
        //return 0;
}


    printf("%s 
",(char*)argv[1]);
    mymain((char*)argv[1]);
    //mymain();
    return 0;
}



AVInputFormat mFormat;
AVDictionary*iformat_opts;
using namespacestd;
#define INBUF_SIZE 4096
intvideoIndex;
#define DelayTime 5
voidInit()
{
    av_register_all();
    avfilter_register_all();
    avformat_network_init();
    av_log_set_level(AV_LOG_ERROR);
}
AVFormatContext *ic =NULL;
int64_t lastReadPacktTime ;
std::shared_ptr <AVPacket>readPacketFromSource()
{
    std::shared_ptr<AVPacket> packet(static_cast<AVPacket*>(av_malloc(sizeof(AVPacket))), [&](AVPacket *p) { av_packet_free(&p); av_freep(&p);});
    av_init_packet(packet.get());
    lastReadPacktTime =av_gettime();
    int ret = av_read_frame(ic, packet.get());
    if(ret >= 0)
    {
        returnpacket;
    }
    else{
        returnnullptr;
    }

}    
bool videoDecode(AVPacket* packet, AVFrame *frame)
{
    int gotFrame = 0;
    //videoIndex
    auto hr = avcodec_decode_video2(ic->streams[videoIndex]->codec, frame, &gotFrame, packet);
    if (hr >= 0 && gotFrame != 0)
    {
        return true;
    }
    return false;
}


intinitVideoDecodeContext()
{    
    auto codecId = ic->streams[videoIndex]->codec->codec_id;
    auto codec =avcodec_find_decoder(codecId);
    if (!codec)
    {
        return -1;
    }

    int ret = avcodec_open2(ic->streams[videoIndex]->codec, codec, NULL);
    returnret;

}



static void pgm_save(unsigned char *buf, int wrap, int xsize, intysize,
                     char *filename)
{
    FILE *f;
    inti;
    printf("filename = %s
",filename);
    f = fopen(filename,"w");
    fprintf(f, "P5
%d %d
%d
", xsize, ysize, 255);
    for (i = 0; i < ysize; i++)
        fwrite(buf + i * wrap, 1, xsize, f);
    fclose(f);
}

int gWidth = 0;
int gHeight = 0;

int linesize[5] = { 640,320,320,0,0};



typedef struct{
    //BYTE  buf[640*360*3/2+100];
    std::shared_ptr<BYTE>buf;
    BYTE*    data[3];
    int64_t  dts;
} DecodeFrame;

//queue<DecodeFrame*> queFrame;

queue<std::shared_ptr<DecodeFrame>>queFrame;

int playState = 1;
std::shared_ptr<CGSDLRender>sdlRender;
mutex g_lock;
int64_t lastDts=0;
unsigned long lastTime = 0;



voidplayFun(){
    
    for(;;){
        if(playState == 0) break;
        if (queFrame.size()>0){

            g_lock.lock();
            //DecodeFrame* dfr= queFrame.front();
            std::shared_ptr<DecodeFrame> dfr=queFrame.front();

            queFrame.pop();
            g_lock.unlock();
            auto diff = dfr->dts -lastDts;
            int duration = diff * 1000 /(ic->streams[videoIndex]->time_base.den
                        /ic->streams[videoIndex]->time_base.num);
            if(duration > DelayTime && duration < 1000){
                Sleep(duration );
            }

            std::cout<<"duration1: "<<duration<<endl;

            printf("packet->dts time =%d --->
 ", dfr->dts * 1000 / (ic->streams[videoIndex]->time_base.den
                / ic->streams[videoIndex]->time_base.num));

            sdlRender->Display((char**)dfr->data,linesize);
            lastDts = dfr->dts;
            unsigned long nowTime =GetTickCount();
            printf("%ld cha  %ld
",nowTime,nowTime-lastTime); //得到ms
            lastTime =nowTime;
            //delete dfr;
}else{
            Sleep(150);
        }
    }
}


int mymain(char*file)
{
    int scan_all_pmts_set = 0;
    /*register all codecs, demux and protocols */Init();
    ic =avformat_alloc_context();
    intret;
    if (!ic) {
        av_log(NULL, AV_LOG_FATAL, "Could not allocate context.
");
        ret =AVERROR(ENOMEM);
        printf("alloc err %d
",ret);
    }

    int err = avformat_open_input(&ic, "F://test.mp4", nullptr, nullptr);
    //int err = avformat_open_input(&ic, "F://3s.mp4", nullptr, nullptr);
    if (err < 0) {
        printf("open err err=%d
",err);
    }
    printf("come 2
");

    err =avformat_find_stream_info(ic, nullptr);
    printf("ic->nb_streams %d
",ic->nb_streams);
    if(err<0){

    }else{
        for(int i=0;i<ic->nb_streams;i++){
            int type =  ic->streams[i]->codec->codec_type;
            printf("type = %d
",type);
            if(type ==AVMediaType::AVMEDIA_TYPE_VIDEO){
                videoIndex  =i;
                printf("videoIndex =%d 
",videoIndex);
            }
        }                                        
    }

    gWidth = ic->streams[videoIndex]->codec->width;
    gHeight = ic->streams[videoIndex]->codec->height;

    int ret1 =initVideoDecodeContext();
    printf("ret1 = %d
",ret1);
    //std::shared_ptr<CGSDLRender>
        sdlRender =std::make_shared<CGSDLRender>();//???????
    ret =initVideoDecodeContext();
    if(ret < 0) returnret;
    sdlRender->InitVideo(0);

    sdlRender->CreateVideoSurface(gWidth, gHeight);
    AVRational time_base =ic->streams[videoIndex]->time_base;
    printf("num %d,den %d--
",time_base.num,time_base.den);
    //to thi
    playState = 1;
    thread t1(playFun);
    t1.detach();
    int64_t lastDts=0;

    int w =gWidth;
    int h =gHeight;
    AVFrame * videoFrame =av_frame_alloc();
    for(int i=0;i<10000;i++){
        auto packet =readPacketFromSource();
        if(packet){
            if(packet->stream_index==videoIndex){
                
                if(videoDecode(packet.get(),videoFrame))
                {

                    printf("%d---
",i);
                    //printf("%lld 
",videoFrame->pkt_pos );

                    //DecodeFrame* dfr=&arrFrame[decodeFrame];
                    //DecodeFrame* dfr = new DecodeFrame;
                    std::shared_ptr<DecodeFrame> dfr(static_cast<DecodeFrame*>( new DecodeFrame), [&](DecodeFrame *p) { deletep;});

                     std::shared_ptr<BYTE> tmpbuf (new BYTE[w * h * 3 / 2 + 100](), std::default_delete<BYTE[]>());
                     dfr->buf =tmpbuf;

                    memcpy(dfr->buf.get(),videoFrame->data[0],w*h);
                    memcpy(dfr->buf.get() + w * h, videoFrame->data[1], w * h / 4);
                    memcpy(dfr->buf.get() + w * h * 5 / 4, videoFrame->data[2], w * h / 4);
                    dfr->data[0] = dfr->buf.get();
                    dfr->data[1] = dfr->buf.get() + w *h;
                    dfr->data[2] = dfr->buf.get() + w * h * 5 / 4;
                    dfr->dts = packet->dts;


                    g_lock.lock();
                    queFrame.push(dfr);
                    g_lock.unlock();
                    printf("packet->dts time =%d <---
 ",dfr->dts*1000/(ic->streams[videoIndex]->time_base.den
                    /ic->streams[videoIndex]->time_base.num));
                    if(queFrame.size()>30)
                            Sleep(100);

                }
            }
        }
        else{
            break;
        }
    }

    av_frame_free(&videoFrame);
    //playFun();
    Sleep(8000);
    playState = 0;
    Sleep(600);
    system("PAUSE");
    
    return 0;
}

免责声明:文章转载自《智能指针处理---bo》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇WPF 中 UserControl作为另一个Process宿主到Window里, ErrorTemplate的默认红框没有出现Java导出CSV文件下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Linux环境下实现对文件读写操作

Linux环境下实现对文件读写操作 ---- 今天分享一下在linux系统在实现对文件读写一些基本的操作,在这之前我们要掌握一些基本的技能在Linux环境下。比如查看命令和一个函数的具体用法,就是相当于查手册,在Linux下有一个man手册非常有用:man查询手册man 1 +命令 这里的1表示为查询的是Linux命令man 2 xxx 这里的2表示为查...

Java虚拟机14:Java对象大小、对象内存布局及锁状态变化

一个对象占多少字节? 关于对象的大小,对于C/C++来说,都是有sizeof函数可以直接获取的,但是Java似乎没有这样的方法。不过还好,在JDK1.5之后引入了Instrumentation类,这个类提供了计算对象内存占用量的方法。至于具体Instrumentation类怎么用就不说了,可以参看这篇文章如何精确地测量java对象的大小。 不过有一点不同的...

C++中的函数指针模板

所谓函数指针模板,就是指向函数模板的函数指针,也可以称为泛型函数指针。 问题描述:定义了一类函数模板,而且这类函数模板有共同的接口,即一致的参数列表。那么如何定义一个函数指针,使这个函数指针可以指向这一类中的所有函数模板呢? 一、先我们应当明确一点,在C++中,模板函数仅仅是一个用来生成函数的代码块,它本身是没有实体的,也就没有与“未被实例化的那些代码”...

《C++ Qt设计模式》 第一章 C++ 简介

第1 章 C++简介 内容: 编译相关     Qt提供了一个qmake工具,它会产生Makefile 文件。使用qmake -project 命令产生一个简单的工程文件。当执行这个命令时,qmake 会将当前工作目录下的全部源文件作为SOURCES列出来,而将全部头文件作为HEADERS 列出来     使用make 重新编译那些发生了变化的文件,或...

再探NSString

再探NSString NSString应该是oc开发中最常用的一个数据类型了,这次对该类型再进行一次全方位的探索与总结。 NSString本质上属于OC类对象,继承于NSObject,遵守NSCopying, NSMutableCopying, NSSecureCoding协议。 NSMutableString与之类似,唯一不同的是它继承于NSStrin...

SetFilePointer 使用

今天在使用SetFilePointer 的时候出现了溢出的问题,使用了SetFilePointerEx,出现了指针错位的问题,其实只要设置LONGLONG64位,然后分别设置SetFilePointer 的高低位不会出现溢出的问题 下面是转的一篇使用这个接口的博文 DWORD SetFilePointer(   HANDLE hFile,   LONG...