| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2259 人关注过本帖
标题:各位大哥帮个忙,小弟写的avi播放时没有视频只有音频啊~~~~
只看楼主 加入收藏
dzhwei0314
Rank: 1
等 级:新手上路
帖 子:3
专家分:0
注 册:2011-12-19
结帖率:0
收藏
已结贴  问题点数:5 回复次数:4 
各位大哥帮个忙,小弟写的avi播放时没有视频只有音频啊~~~~
//格式转换线程
void CodecThread (void * param)
{
    CKPlayerDlg * pDlg = (CKPlayerDlg *)param;
    AVCodec *decoder = NULL;
    AVCodec *encoder = NULL;
    AVCodecContext *pCodecCtx264 = NULL;
    AVCodecContext *pCodecCtxMpeg = NULL;
    AVFrame * picture1 = NULL;        //从264解出的yuv数据
    AVFrame * picture2 = NULL;        //从yuv向MPEG2输入的数据
    unsigned int out_size = 0;
    int outbuf_size = 200000;        //mpeg2编码后一帧最大长度

    BYTE * outbuf = NULL;
    BYTE * yuv = NULL;
    BYTE *dst_ori = NULL;
    int videoWidth = 0;
    int videoHeight = 0;
    int bpp = 24;
    FILE * fp264 = NULL;
    FILE * fpspx = NULL;
    FILE * fppcm = NULL;
    POSITION pos = 0;
    CString FileName;
    int remain_264 = 0;
    unsigned int i = 0;
    int frame_count = 0;
    int bytes_used = 0;
    int got_picture = 0;
    int total_frame = 0;
    int play_time = 0;
    KONESTREAMHEADER File_head = {0};


    WAVEFILEHEAD m_wavhead;
    WAVEFORMATEX wfx;
    int m_Size = 0;

    int Vedio_enable = 1;


    /*Holds the audio that will be written to file (16 bits per sample)*/
    short pcm_buf [160*3] = {0};
    /*Speex handle samples as float, so we need an array of floats*/
    int frame_len = 60;
    char spx_buf [100] = {0};
    /*Holds the state of the decoder*/
    void * state = NULL;
    /*Holds bits so they can be read and written to by the Speex routines*/
    SpeexBits bits;
    int tmp = 0;
    BOOL firstrun = TRUE;

    CString m_strPath;
    CString file;

    GetModuleFileName(NULL,m_strPath.GetBufferSetLength(MAX_PATH+1),MAX_PATH);   
    m_strPath.ReleaseBuffer();   
    int  nPos;
    nPos=m_strPath.ReverseFind('\\');   
    m_strPath=m_strPath.Left(nPos);


    BYTE *buf_264;
    buf_264 = new BYTE[1024*100];
    if (!buf_264)
    {
        AfxMessageBox("申请内存失败!");
        return;
    }

   // wav头初始化
     wfx.wFormatTag = WAVE_FORMAT_PCM;
     wfx.nChannels = 1;
     wfx.nSamplesPerSec = WISA_POOR;
     wfx.nAvgBytesPerSec = 1 * WISA_POOR * 16 / 8;
     wfx.nBlockAlign = 16 * 1 / 8;
     wfx.wBitsPerSample = 16;
     wfx.cbSize = 0;
   
    memcpy(m_wavhead.szRIFF, "RIFF", 4);   
    m_wavhead.dwTotalSize = m_Size + sizeof(WAVEFILEHEAD) - 8;   
    memcpy(m_wavhead.szWAVE, "WAVE", 4);   
    memcpy(m_wavhead.szFMT, "fmt ", 4);   
    m_wavhead.dwChunk0Size = 16;   
    memcpy(m_wavhead.Format, &wfx, 16);   
    memcpy(m_wavhead.szDATA, "data", 4);   
    m_wavhead.dwChunk1Size = m_Size;


    //音频初始化
    /*Create a new decoder state in narrowband mode*/
    state = speex_decoder_init(speex_lib_get_mode(SPEEX_MODEID_NB));
    /*Set the perceptual enhancement on*/
    tmp = 1;
    speex_decoder_ctl(state, SPEEX_SET_ENH, &tmp);
    /*Initialization of the structure that holds the bits*/
    speex_bits_init(&bits);
    //音频初始化

    //解码H.264
    decoder = avcodec_find_decoder(CODEC_ID_H264);
    if (!decoder)
    {
        AfxMessageBox ("加载解码器失败");
        goto exit0;
    }

    pCodecCtx264 = avcodec_alloc_context();
    pCodecCtxMpeg = avcodec_alloc_context();
    picture1 = avcodec_alloc_frame();
    picture2 = avcodec_alloc_frame();

    if (decoder->capabilities & CODEC_CAP_TRUNCATED)
        pCodecCtx264->flags |= CODEC_FLAG_TRUNCATED;    //we dont send complete frames

    // for some codecs, such as msmpeg4 and mpeg4, width and height
    // MUST be initialized there because these info are not available
    // in the bitstream
    if (avcodec_open(pCodecCtx264, decoder) < 0)
    {
        AfxMessageBox ("打开解码器失败");
        goto exit1;
    }

    encoder = avcodec_find_encoder(CODEC_ID_MPEG2VIDEO);
    if (!encoder)
    {
        AfxMessageBox ("加载编码器失败\n");
        goto exit2;
    }

    pDlg->m_playprogress.ShowWindow(SW_SHOW);

////////////////////////////////////////////打开文件///////////////////////////////////////
    FileName = pDlg->m_FileName;

    fp264 = fopen (FileName.LockBuffer(), "rb");
    if (!fp264)
    {
        AfxMessageBox ("打开原始视频文件失败");
        Vedio_enable = 0;
        goto exit2;
    }
    else
    {
        Vedio_enable = 1;
    //    Vedio_enable = 0;
    //    FileName = FileName.Left(FileName.GetLength()-4);
    }

//    if(Vedio_enable)
    {
        FileName = FileName.Left(FileName.GetLength()-4);
        file = FileName;
        int pp=0,ll=0;
        while ((ll=file.Find('\\',pp+1))>0)
        {
            pp = ll;
        }
        file = file.Right(file.GetLength()-pp);
        m_strPath += file;
   
    FileName += ".aud";            //将扩展名替换为".spx"
    fpspx = fopen (FileName.LockBuffer(), "rb");
    if (!fpspx)
    {
        AfxMessageBox ("打开原始音频文件失败");
        pDlg->m_bAudioEnable=FALSE;
//        goto exit2;
    }
    else
    {
        pDlg->m_bAudioEnable=TRUE;
    }

    if (pDlg->m_bAudioEnable)
    {
        
        fseek (fpspx, sizeof(KONESTREAMHEADER), SEEK_CUR);

//        m_strPath = m_strPath.Left(m_strPath.GetLength()-4);
        m_strPath += ".wav";            //将扩展名替换为".spx"
        fppcm = fopen (m_strPath.LockBuffer(), "wb");
        if (!fppcm)
        {
            AfxMessageBox ("打开原始音频文件失败");
            goto exit2;
        }
        fwrite(&m_wavhead,1, sizeof(WAVEFILEHEAD),fppcm);
    }


    if(Vedio_enable)
    {
        if (1 != fread (&File_head, sizeof(KONESTREAMHEADER), 1, fp264))        //读取文件头
        {
            AfxMessageBox ("读取原始视频文件失败");
            goto exit2;
        }
        if (NULL == strstr (File_head.fcc, "KONE"))
        {
            AfxMessageBox("原始视频文件已损坏");
            goto exit2;
        }

        //put sample parameters
        pCodecCtxMpeg->bit_rate = 4000000;
        //resolution must be a multiple of two
        pCodecCtxMpeg->width = File_head.width;
        pCodecCtxMpeg->height = File_head.height;
        //frames per second
        pCodecCtxMpeg->time_base.num = 1;
        pCodecCtxMpeg->time_base.den = 25;

        pCodecCtxMpeg->gop_size = 10;    //emit one intra frame every ten frames
        pCodecCtxMpeg->max_b_frames = 1;
        pCodecCtxMpeg->pix_fmt = PIX_FMT_YUV420P; // PIX_FMT_BGR24

        m_Size = 0;
    }
   

    //avi初始化
    AVIFileInit();
   
    //
    // Create AVI file
    //
    if (pDlg->m_bAudioEnable)
    {
        m_strPath = m_strPath.Left(m_strPath.GetLength()-4);
    }
    m_strPath += ".avi";

    PAVIFILE pAviFile = NULL;

    HRESULT hr = AVIFileOpen( &pAviFile, m_strPath, OF_WRITE | OF_CREATE, NULL );
    if ( 0 != hr )
    {
        ASSERT( FALSE );
        return;
    }

    //
    // Create AVI video stream
    //
    AVISTREAMINFO strhdr;
    PAVISTREAM pAviStream = NULL;
    BITMAPINFOHEADER bih;
    int nFrames = 0;
   
    UINT pitch;
    UINT biSizeImage;
        memset( &strhdr, 0, sizeof( strhdr ) );

    fseek (fp264, sizeof(KONESTREAMHEADER), SEEK_SET);


    if (1 != fread (&i, 4, 1, fp264))
    {
    //    break;
    }
    fseek (fp264, 4, SEEK_CUR);            //忽略时间戳
    i -= 4;                                //去除时间戳长度
    if (i<0 || i>102400)
    {
        AfxMessageBox ("视频文件异常");
        goto exit2;
    }
    if (i != fread(buf_264+remain_264, 1, i, fp264))
    {
    //    break;
    }
    remain_264 += i;
            
    bytes_used = avcodec_decode_video(pCodecCtx264, picture1, &got_picture, buf_264, remain_264);
   
    //avi 视频初始化
    // Calc image size
    videoWidth = pCodecCtx264->width;
    videoHeight = pCodecCtx264->height;
               
    strhdr.fccType = streamtypeVIDEO;
    strhdr.fccHandler = 0;
    strhdr.dwScale = 1;
    strhdr.dwRate = 25;
    pitch = ( videoWidth * bpp + 31 ) / 32 * 4;
    biSizeImage = ( videoWidth * bpp + 31 ) / 32 * 4 * videoHeight;
    strhdr.dwSuggestedBufferSize = biSizeImage;
    SetRect( &strhdr.rcFrame, 0, 0, videoWidth, videoHeight );
   
    // And create the stream;
   
    hr = AVIFileCreateStream( pAviFile, &pAviStream, &strhdr );
    if ( 0 != hr )
    {
        ASSERT( FALSE );
        
        AVIFileRelease( pAviFile );
        pAviFile = NULL;
        
        return;
    }
   
    //
    // Set stream format
    //
   
    memset( &bih, 0, sizeof( BITMAPINFOHEADER ) );
   
   
    bih.biSize = sizeof(BITMAPINFOHEADER);
    bih.biWidth = videoWidth;
    bih.biHeight = videoHeight;
    bih.biBitCount = 0;
    bih.biCompression = '462H';
    bih.biSizeImage = 0;
    bih.biPlanes = 1;        
    hr = AVIStreamSetFormat( pAviStream, 0, &bih, sizeof( bih ) );
    if ( 0 != hr )
    {
        ASSERT( FALSE );
        
        AVIStreamClose( pAviStream );
        pAviStream = NULL;
        
        AVIFileRelease( pAviFile );
        pAviFile = NULL;
    }

    //
    // Create AVI Audio stream
    //
    AVISTREAMINFO m_AVIAudioStreamInfo;
    PAVISTREAM m_aviAudeoStream;
    int nAudios = 0;
   
    //设置音频流格式
    m_AVIAudioStreamInfo.fccType = streamtypeAUDIO;         
    m_AVIAudioStreamInfo.dwScale = 1; //声道数         
    m_AVIAudioStreamInfo.dwRate = 8000; //Hz         
    m_AVIAudioStreamInfo.dwSuggestedBufferSize = 32768;         
    m_AVIAudioStreamInfo.dwSampleSize = 1;         
    //    m_AVIAudioStreamInfo.fccHandler = mmioFOURCC('g','7','1','1');     
    m_AVIAudioStreamInfo.fccHandler = 0;
    m_AVIAudioStreamInfo.dwFlags = 0;         
    m_AVIAudioStreamInfo.dwCaps = 0;         
    m_AVIAudioStreamInfo.wPriority = 0;         
    m_AVIAudioStreamInfo.wLanguage = 0;         
    m_AVIAudioStreamInfo.dwStart = 0;         
    m_AVIAudioStreamInfo.dwInitialFrames = 1;                 
    m_AVIAudioStreamInfo.dwQuality = 0;         
    m_AVIAudioStreamInfo.rcFrame.bottom = 0;         
    m_AVIAudioStreamInfo.rcFrame.left = 0;         
    m_AVIAudioStreamInfo.rcFrame.right = 0;         
    m_AVIAudioStreamInfo.rcFrame.top = 0;         
    m_AVIAudioStreamInfo.dwEditCount = 0;         
    m_AVIAudioStreamInfo.dwFormatChangeCount = 0;         
    m_AVIAudioStreamInfo.dwLength = 0;
    if (pDlg->m_bAudioEnable)
    {
        AVIFileCreateStream(pAviFile,&m_aviAudeoStream,(AVISTREAMINFO *)&m_AVIAudioStreamInfo);   
    }

    //音频
   
    if (pDlg->m_bAudioEnable)
    {   
        
        WAVEFORMATEX waveFormat;
        
        waveFormat.wFormatTag = WAVE_FORMAT_PCM;
        waveFormat.nChannels = 1;
        waveFormat.nSamplesPerSec = WISA_POOR;
        waveFormat.nAvgBytesPerSec = WISA_POOR * 16 * 1 / 8;
        waveFormat.nBlockAlign = 16 * 1 / 8;
        waveFormat.wBitsPerSample = 16;
        waveFormat.cbSize = 0;
        
        AVIStreamSetFormat(m_aviAudeoStream,0,&waveFormat,sizeof(waveFormat));
            
        //音频格式转换
        
        while (1)
        {
            /*Read the "packet" encoded by sampleenc*/
            if (fseek (fpspx, 4, SEEK_CUR))                    //跳过帧长度4字节
            {
                break;
            }
            if (fseek (fpspx, 4, SEEK_CUR))                    //跳过时间戳
            {
                break;
            }
            if (1 != fread (spx_buf, frame_len, 1, fpspx))        //读取一帧20字节
            {
                break;
            }
            
            
            for (int j=0; j<3; j++)                //分三次解码,每次20字节
            {
                /*Copy the data into the bit-stream struct*/
                speex_bits_read_from (&bits, spx_buf+j*20, 20);
                /*Decode the data*/
                speex_decode_int (state, &bits, (__int16 *)pcm_buf+j*160);
            }
            if (0 >= fwrite ((char *)pcm_buf, 1, 160*2*3, fppcm))  // pcmbuf是short类型的
            {
                break;
            }
            m_Size += 160*2*3;
            hr = AVIStreamWrite( m_aviAudeoStream, nAudios, 1, pcm_buf, 160*2*3, AVIIF_KEYFRAME, NULL, NULL );
            nAudios++;
        }
        
        m_wavhead.dwTotalSize = m_Size + sizeof(WAVEFILEHEAD) - 8;
        m_wavhead.dwChunk1Size = m_Size;   
        fseek(fppcm,0, SEEK_SET);
        fwrite(&m_wavhead,1, sizeof(WAVEFILEHEAD),fppcm);
        
        AVIStreamClose( m_aviAudeoStream );
        m_aviAudeoStream = NULL;     
    }

//视频
    if(Vedio_enable)
    {   
        //设置进度条
        if (!pDlg->m_bVideoEnable)
        {
            total_frame = GetTotalFrame (fp264);
            //总进度
            pDlg->m_pro.SetRange(0,(short)File_head.totalFrames*5/3);
            pDlg->m_pro.SetStep(1);
            pDlg->m_pro.SetPos(0);
            frame_count = 0;
            ::SetDlgItemText(pDlg->GetSafeHwnd(),IDC_TISHI, "转换进度");
            //pDlg->m_playprogress.SetRange(0,total_frame);
            //pDlg->m_playprogress.SetPos(1);
        }
   
        fseek (fp264, sizeof(KONESTREAMHEADER), SEEK_SET);        //忽略视频文件头

        int aa=1;
        //开始解码
        while (1)
        {
            //读取第二帧
            if (1 != fread (&i, 4, 1, fp264))
            {
                break;
            }
            fseek (fp264, 4, SEEK_CUR);            //忽略时间戳
            i -= 4;                                //去除时间戳长度
            
            if (i<0 || i>102400)
            {
                AfxMessageBox ("视频文件异常");
                goto exit2;
            }
            memset(buf_264,0,1024*3);
            if (i != fread(buf_264, 1, i, fp264))
            {
                break;
            }
            hr = AVIStreamWrite( pAviStream, nFrames, 1, buf_264, i, AVIIF_KEYFRAME, NULL, NULL );
            remain_264 -= i;

            if (!pDlg->m_bVideoEnable)
            {
                pDlg->m_pro.StepIt();
            }
            nFrames++;
        }   

        AVIStreamClose( pAviStream );
        pAviStream = NULL;
    }

    ::SetDlgItemText(pDlg->GetSafeHwnd(),IDC_TISHI, "转换完成");

    // some codecs, such as MPEG, transmit the I and P frame with a latency of one frame.
    // You must do the following to have a chance to get the last frame of the video

   
    if ( pAviFile )
    {
        AVIFileRelease( pAviFile );
        pAviFile = NULL;
    }
   
    AVIFileExit();

    if (fp264)
    {
        fclose (fp264);
    }
//    if (fpmpeg)
//    {
//        fclose (fpmpeg);
//    }
     if (fpspx)
    {
        fclose (fpspx);
    }
    if (fppcm)
    {
        fclose (fppcm);
    }
    AfxMessageBox("格式转换完成");

    pDlg->CodecEnable = FALSE;
    return;
}

exit2:
    avcodec_close(pCodecCtxMpeg);
    av_free(pCodecCtxMpeg);

exit1:
    avcodec_close(pCodecCtx264);
    av_free(pCodecCtx264);

exit0:
    /*Destroy the decoder state*/
    speex_decoder_destroy(state);
    /*Destroy the bit-stream truct*/
    speex_bits_destroy(&bits);

    delete [] buf_264;

    if (picture1)
    {
        av_free (picture1);
    }
    if (picture2)
    {
        av_free (picture2);
    }
    if (yuv)
    {
        free (yuv);
    }
    if (outbuf)
    {
        free (outbuf);
    }
    if (fp264)
    {
        fclose (fp264);
    }
//    if (fpmpeg)
//    {
//        fclose (fpmpeg);
//    }
    if (fpspx)
    {
        fclose (fpspx);
    }
    if (fppcm)
    {
        fclose (fppcm);
    }

    if (pDlg->FullWindows)
    {
        pDlg->OnFullScreen();
    }

    ::SetDlgItemText(pDlg->GetSafeHwnd(),IDC_STATIC_STATUS, "转换格式完成");
    pDlg->CodecEnable = FALSE;
}
搜索更多相关主题的帖子: 格式转换 视频 大哥 
2011-12-19 17:33
dzhwei0314
Rank: 1
等 级:新手上路
帖 子:3
专家分:0
注 册:2011-12-19
收藏
得分:0 
自己顶下~~~~
各位高手帮帮小弟吧~~~~
2011-12-19 17:33
编程的乐趣
Rank: 9Rank: 9Rank: 9
等 级:蜘蛛侠
威 望:1
帖 子:229
专家分:1027
注 册:2011-4-4
收藏
得分:3 
.
2011-12-19 17:41
loveminttea
Rank: 3Rank: 3
来 自:河南科技学院
等 级:论坛游侠
帖 子:95
专家分:146
注 册:2010-10-14
收藏
得分:3 
无能为力...
2011-12-25 14:49
dzhwei0314
Rank: 1
等 级:新手上路
帖 子:3
专家分:0
注 册:2011-12-19
收藏
得分:0 
真没人会啊~~~~
2011-12-26 14:01
快速回复:各位大哥帮个忙,小弟写的avi播放时没有视频只有音频啊~~~~
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.131942 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved