⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fframeextractfilter.cpp

📁 6410BSP1
💻 CPP
字号:
//------------------------------------------------------------------------------
// File: fFrameExtractFilter.cpp
//
// Desc: implement CFrameExtractFilter class.
//
// Author : JiyoungShin(idon.shin@samsung.com)
//
// Copyright 2007 Samsung System LSI, All rights reserved.
//------------------------------------------------------------------------------

#include "stdafx.h"
#include "FrameExtractFilter.h"
#include "fFrameExtractFilter.h"
#include "fFrameExtractFilter_op.h"

#include <stdio.h>
#include "FrameExtractor.h"
#include "H264Frames.h"
#include "H263Frames.h"
#include "MPEG4Frames.h"
#include "VC1Frames.h"


static unsigned char delimiter_H264[]  = {0x00, 0x00, 0x00, 0x01}; // H.264
static unsigned char delimiter_MPEG4[] = {0x00, 0x00, 0x01}; //MPEG4


#include "FileRead.h"
#ifndef DATAREAD_TYPE
#error "DATAREAD_TYPE is not defined."
#endif
#if (DATAREAD_TYPE == DATA_FILE)
    #define FRAMEX_IN_TYPE_SEL    (FRAMEX_IN_TYPE_FILE)
#else
    #define FRAMEX_IN_TYPE_SEL    (FRAMEX_IN_TYPE_MEM)
#endif


//
// Constructor
//
CFrameExtractFilter::CFrameExtractFilter(LPUNKNOWN pUnk, HRESULT *phr)
    : CSource(NAME("CFrameExtractFilter"), pUnk, CLSID_FrameExtractFilter),
    m_pwFileName(NULL), m_File(NULL), m_pFramexCtx(NULL)
{
    CAutoLock cAutoLock(&m_cStateLock);

    //
    // CSource::AddPin() is automatically called
    // by creating a source stream (CSourceStream)
    //

    // Add one source stream (output pin)!
    new CFrameExtractFilterStream(phr, this, L"Out");

    m_first = 1;
}


//
// Destructor
//
CFrameExtractFilter::~CFrameExtractFilter()
{
    // Close file
    if (m_File)
        SSB_FILE_CLOSE(m_File);

    if (m_pwFileName)
        delete[] m_pwFileName;

    if (m_pFramexCtx)
        FrameExtractorFinal((FRAMEX_CTX *) m_pFramexCtx);
}


//
// Load
//
STDMETHODIMP CFrameExtractFilter::Load(LPCOLESTR pwszFileName, const AM_MEDIA_TYPE *pmt)
{
    // IFileSourceFilter::Load()
    // Any calls to this method after the first call will fail!

    if (m_pwFileName)
        return E_FAIL;

    CheckPointer(pwszFileName, E_POINTER);

    // lstrlenW is one of the few Unicode functions that works on win95
    DWORD dwSize = lstrlenW(pwszFileName) + 1;

    TCHAR pszFileName[MAX_PATH] = {0};
    lstrcpy(pszFileName, pwszFileName);

    CAutoLock lck(&m_cStateLock);

    // file checking
    HRESULT hr = CheckFile(pszFileName, pmt);
    
    if (FAILED(hr))
        return E_FAIL;

    // Restore the current file name
    m_pwFileName = new WCHAR[dwSize];

    if (m_pwFileName != NULL)
        CopyMemory(m_pwFileName, pwszFileName, dwSize * sizeof(WCHAR));

    return S_OK;
}


//
// GetCurFile
//
STDMETHODIMP CFrameExtractFilter::GetCurFile(LPOLESTR *ppwszFileName, AM_MEDIA_TYPE *pmt)
{
    CheckPointer(ppwszFileName, E_POINTER);
    *ppwszFileName = NULL;

    if (m_pwFileName != NULL) 
    {
        DWORD dwSize = sizeof(WCHAR) * (1 + lstrlenW(m_pwFileName));
        
        *ppwszFileName = (LPOLESTR)CoTaskMemAlloc(dwSize);
        if (*ppwszFileName != NULL) 
        {
            CopyMemory(*ppwszFileName, m_pwFileName, dwSize);
        
        }
    }

    if (pmt != NULL) 
    {
        CopyMediaType(pmt, &m_mt);
    }

    return S_OK;
}


int CFrameExtractFilter::GetNextFrame(unsigned char *pFrameBuf, unsigned int *pSize)
{
    int nRead;


    // 贸澜 龋免登绰 版快绰 config stream阑 府畔茄促.
    if (m_first) {
        switch (m_StrmType) {
        case RAW_STRM_TYPE_M4V:
            m_pFramexCtx = FrameExtractorInit(FRAMEX_IN_TYPE_SEL, delimiter_MPEG4, 3, 1);
            FrameExtractorFirst((FRAMEX_CTX *) m_pFramexCtx, m_File);
            nRead = ExtractConfigStreamMpeg4((FRAMEX_CTX *) m_pFramexCtx, m_File, pFrameBuf, *pSize, NULL);
            break;

        case RAW_STRM_TYPE_H264RAW:
            m_pFramexCtx = FrameExtractorInit(FRAMEX_IN_TYPE_SEL, delimiter_H264, 4, 1);
            FrameExtractorFirst((FRAMEX_CTX *) m_pFramexCtx, m_File);
            nRead = ExtractConfigStreamH264((FRAMEX_CTX *) m_pFramexCtx, m_File, pFrameBuf, *pSize, NULL);
            break;

        case RAW_STRM_TYPE_RCV:
            nRead = ExtractConfigStreamVC1(m_File, pFrameBuf, *pSize, NULL);
            break;

        default:
            return -1;
        }

        m_first = 0;

        return nRead;
    }

    switch (m_StrmType) {
    case RAW_STRM_TYPE_M4V:
        nRead = NextFrameMpeg4((FRAMEX_CTX *) m_pFramexCtx, (FILE *) m_File, pFrameBuf, *pSize, NULL);
        break;

    case RAW_STRM_TYPE_H264RAW:
        nRead = NextFrameH264((FRAMEX_CTX *) m_pFramexCtx, (FILE *) m_File, pFrameBuf, *pSize, NULL);
        break;

    case RAW_STRM_TYPE_RCV:
        nRead = NextFrameVC1(m_File, pFrameBuf, *pSize, NULL);
        break;

    default:
        return -1;
    }
    
    if (nRead <= 5)
        return -1;

    return nRead;
}


//
// ReadTheFile
//
HRESULT CFrameExtractFilter::CheckFile(LPCTSTR pszFileName, const AM_MEDIA_TYPE *pmt)
{
    TCHAR         file_ext[4];

    int           nRead;
    unsigned int  width, height;
    union {
        MPEG4_CONFIG_DATA mpeg4_conf;
        H263_CONFIG_DATA  h263_conf;
        H264_CONFIG_DATA  h264_conf;
        VC1_CONFIG_DATA   vc1_conf;
    } u;

    unsigned char *p_confbuf;


#define FILE_EXT_M4V    L".m4v"
#define FILE_EXT_H264    L".264"
#define FILE_EXT_RCV    L".rcv"

    if (wcslen(pszFileName) > 4)
        wcsncpy(file_ext, pszFileName + (wcslen(pszFileName) - 4), 4);
    else
        file_ext[0] = 0;

    // Identify the codec type according to the filename extention
    if(_wcsnicmp(file_ext, FILE_EXT_M4V, 4) == 0)
        m_StrmType = RAW_STRM_TYPE_M4V;
    else if(_wcsnicmp(file_ext, FILE_EXT_H264, 4) == 0)
        m_StrmType = RAW_STRM_TYPE_H264RAW;
    else if(_wcsnicmp(file_ext, FILE_EXT_RCV, 4) == 0)
        m_StrmType = RAW_STRM_TYPE_RCV;
    else{
        RETAILMSG(1, (L"[FrameExtractFilter]unsupported file type(%s)\n", pszFileName));
        return E_FAIL;
    }

    // Open file
    m_File = SSB_FILE_OPEN(pszFileName);
    if (m_File == NULL){
        RETAILMSG(1, (L"[FrameExtractFilter]file(%s) doesn't exist\n", pszFileName));
        return E_FAIL;
    }

#define CONFIG_STRM_LENG_MAX    (128 * 1024)    // 128 KB
    p_confbuf = (unsigned char *) malloc(CONFIG_STRM_LENG_MAX);
    if (p_confbuf == NULL) {
        RETAILMSG(1, (L"[FrameExtractFilter] memory allocation for CONFIG_STRM failed.\n"));
        SSB_FILE_CLOSE(m_File);
        return E_FAIL;
    }
    // Obtaininig Width, Height
    memset(&u, 0, sizeof(u));
    switch (m_StrmType) {
    case RAW_STRM_TYPE_M4V:
        m_pFramexCtx = FrameExtractorInit(FRAMEX_IN_TYPE_SEL, delimiter_MPEG4, 3, 1);
        FrameExtractorFirst((FRAMEX_CTX *) m_pFramexCtx, m_File);
        nRead = ExtractConfigStreamMpeg4((FRAMEX_CTX *) m_pFramexCtx, m_File, p_confbuf, CONFIG_STRM_LENG_MAX, &(u.mpeg4_conf));
        FrameExtractorFinal((FRAMEX_CTX *) m_pFramexCtx);
        m_pFramexCtx = NULL;

        width  = u.mpeg4_conf.width;
        height = u.mpeg4_conf.height;
        break;

    case RAW_STRM_TYPE_H264RAW:
        m_pFramexCtx = FrameExtractorInit(FRAMEX_IN_TYPE_SEL, delimiter_H264, 4, 1);
        FrameExtractorFirst((FRAMEX_CTX *) m_pFramexCtx, m_File);
        nRead = ExtractConfigStreamH264((FRAMEX_CTX *) m_pFramexCtx, m_File, p_confbuf, CONFIG_STRM_LENG_MAX, &(u.h264_conf));
        FrameExtractorFinal((FRAMEX_CTX *) m_pFramexCtx);
        m_pFramexCtx = NULL;

        width  = u.h264_conf.width;
        height = u.h264_conf.height;
        break;

    case RAW_STRM_TYPE_RCV:
        nRead = ExtractConfigStreamVC1(m_File, p_confbuf, CONFIG_STRM_LENG_MAX, &(u.vc1_conf));

        width  = u.vc1_conf.width;
        height = u.vc1_conf.height;
        break;

    default:
        free(p_confbuf);
        SSB_FILE_CLOSE(m_File);
        return E_FAIL;
    }

    // Close file
    free(p_confbuf);
    SSB_FILE_CLOSE(m_File);


    // Validate the width & height value
    if ((width > 720) || (width < 16) || (height > 576) || (height < 16)) {
        RETAILMSG(1, (L"[FrameExtractFilter] video size is too big. (width=%d, height=%d)\n", width, height));
        return E_FAIL;
    }

    // Open file
    m_File = SSB_FILE_OPEN(pszFileName);
    if (m_File == NULL){
        RETAILMSG(1, (L"[FrameExtractFilter]file(%s) doesn't exist\n", pszFileName));
        return E_FAIL;
    }


    // Setting MediaType
    CMediaType mt;

    if (pmt == NULL)
    {
        if (FAILED(MakeMediaType(&mt, width, height)))
        {
            SSB_FILE_CLOSE(m_File);
            return E_FAIL;
        }
    }
    else
        mt = *pmt;

    // this is not a simple assignment... pointers and format
    // block (if any) are intelligently copied
    m_mt = mt;

    return S_OK;
}


//
// MakeMediaType
//
HRESULT CFrameExtractFilter::MakeMediaType(CMediaType *pMediaType, int width, int height)
{
    unsigned int  *size;

    pMediaType->InitMediaType();
    pMediaType->SetType(&MEDIATYPE_Stream);

    switch (m_StrmType) {
    case RAW_STRM_TYPE_M4V:
        pMediaType->SetSubtype(&MEDIASUBTYPE_m4v);
        break;

    case RAW_STRM_TYPE_H264RAW:
        pMediaType->SetSubtype(&MEDIASUBTYPE_h264raw);
        break;

    case RAW_STRM_TYPE_RCV:
        pMediaType->SetSubtype(&MEDIASUBTYPE_rcv);
        break;

    default:
        RETAILMSG(1, (L"[FrameExtractFilter]unsupported file type\n"));
        return E_FAIL;
    }

    size = (unsigned int *) pMediaType->ReallocFormatBuffer(sizeof(unsigned int) * 2);
    size[0] = width;
    size[1] = height;

    pMediaType->SetFormat((BYTE *)size, sizeof(unsigned int) * 2);

    return S_OK;
}

int CFrameExtractFilter::CloseFile()
{
    if (m_File) {
        SSB_FILE_CLOSE(m_File);
        m_File = NULL;
    }

    return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -