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

📄 umc_mpeg4_video_decoder.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
                    if ((mp4_Parse_VisualObjectSequence(m_decInfo)) != MP4_STATUS_OK)
                        return UMC_ERR_INVALID_STREAM;
                }
                if (!h_vo_found && code == MP4_VISUAL_OBJECT_SC) {
                    h_vo_found = 1;
                    if ((mp4_Parse_VisualObject(m_decInfo)) != MP4_STATUS_OK)
                        return UMC_ERR_INVALID_STREAM;
                }
            }
            if ((Ipp32s)code >= MP4_VIDEO_OBJECT_MIN_SC && code <= MP4_VIDEO_OBJECT_MAX_SC) {
                if ((mp4_Parse_VideoObject(m_decInfo)) != MP4_STATUS_OK)
                    return UMC_ERR_INVALID_STREAM;
                break;
            }
            // some streams can start with video_object_layer
            if ((Ipp32s)code >= MP4_VIDEO_OBJECT_LAYER_MIN_SC && code <= MP4_VIDEO_OBJECT_LAYER_MAX_SC) {
                m_decInfo->bufptr -= 4;
                if ((mp4_Parse_VideoObject(m_decInfo)) != MP4_STATUS_OK)
                    return UMC_ERR_INVALID_STREAM;
                break;
            }
        }
    }
    status = AllocateBuffers();
    if (status != UMC_OK)
        return status;
    // set aspect ratio info
    switch (m_decInfo->VisualObject.VideoObject.aspect_ratio_info) {
        case MP4_ASPECT_RATIO_FORBIDDEN:
        case MP4_ASPECT_RATIO_1_1:
            m_Param.info.aspect_ratio_width  = 1;
            m_Param.info.aspect_ratio_height = 1;
            break;
        case MP4_ASPECT_RATIO_12_11:
            m_Param.info.aspect_ratio_width  = 12;
            m_Param.info.aspect_ratio_height = 11;
            break;
        case MP4_ASPECT_RATIO_10_11:
            m_Param.info.aspect_ratio_width  = 10;
            m_Param.info.aspect_ratio_height = 11;
            break;
        case MP4_ASPECT_RATIO_16_11:
            m_Param.info.aspect_ratio_width  = 16;
            m_Param.info.aspect_ratio_height = 11;
            break;
        case MP4_ASPECT_RATIO_40_33:
            m_Param.info.aspect_ratio_width  = 40;
            m_Param.info.aspect_ratio_height = 33;
            break;
        default:
            m_Param.info.aspect_ratio_width  = m_decInfo->VisualObject.VideoObject.aspect_ratio_info_par_width;
            m_Param.info.aspect_ratio_height = m_decInfo->VisualObject.VideoObject.aspect_ratio_info_par_height;
    }
    // set profile/level info
    m_Param.profile = m_decInfo->profile_and_level_indication >> 4;
    m_Param.level = m_decInfo->profile_and_level_indication & 15;
    if (m_Param.profile == MPEG4_PROFILE_SIMPLE)
        if (m_Param.level == 8)
            m_Param.level = MPEG4_LEVEL_0;
    if (m_Param.profile == MPEG4_PROFILE_ADVANCED_SIMPLE) {
        if (m_Param.level == 7)
            m_Param.level = MPEG4_LEVEL_3B;
        if (m_Param.level > 7) {
            m_Param.profile = MPEG4_PROFILE_FGS;
            m_Param.level -= 8;
        }
    }
    m_IsInit = true;
    return UMC_OK;
}

Status MPEG4VideoDecoder::GetFrame(MediaData* in, MediaData* out)
{
    Status  status = UMC_OK;
    Ipp64f  pts = -1.0;

#ifdef _OMP_KARABAS
    m_decInfo->mTreadPriority = vm_get_current_thread_priority();
#endif // _OMP_KARABAS
    if (!m_IsInitBase)
        return UMC_ERR_NOT_INITIALIZED;
    if (!out)
        return UMC_ERR_NULL_PTR;
    if (in) {
        m_decInfo->bitoff = 0;
        m_decInfo->bufptr = m_decInfo->buffer = (Ipp8u *)in->GetDataPointer();
        m_decInfo->buflen = in->GetDataSize();
    }
    if (!m_IsInit) {
        if (in == NULL)
            return UMC_ERR_NOT_ENOUGH_DATA;
        m_Param.m_pData = in;
        status = InsideInit();
        if (status != UMC_OK) {
            in->MoveDataPointer(in->GetDataSize() - m_decInfo->buflen);
            if (status == UMC_ERR_INVALID_STREAM ||
                status == UMC_ERR_SYNC)
                return UMC_ERR_NOT_ENOUGH_DATA;
            else
                return status;
        }
    }
    LockBuffers();
    for (;;) {
        if (in == NULL) {
            // show last frame (it can be only if (m_Param.lFlags & FLAG_VDEC_REORDER))
            if (!m_buffered_frame) {
                UnlockBuffers();
                return UMC_ERR_NOT_ENOUGH_DATA;
            }
            m_buffered_frame = false;
            m_decInfo->VisualObject.vFrame = m_decInfo->VisualObject.VideoObject.prevPlaneIsB ?
                                            &m_decInfo->VisualObject.nFrame : &m_decInfo->VisualObject.cFrame;
        } else {
            // Seeking the VOP start_code, and then begin the vop decoding
            if (m_decInfo->VisualObject.VideoObject.short_video_header) {
                if (!mp4_SeekShortVideoStartMarker(m_decInfo)) {
                    mp4_Error("Error: Failed seeking short_video_start_marker\n");
                    status = UMC_ERR_SYNC;
                    break;
                }
            } else {
                for (;;) {
                    if (!mp4_SeekStartCodePtr(m_decInfo)) {
                        mp4_Error("Error: Failed seeking GOV or VOP Start Code");
                        status = UMC_ERR_SYNC;
                        break;
                    }
                    int code = m_decInfo->bufptr[0];
                    m_decInfo->bufptr ++;
                    // parse repeated VOS, VO and VOL headers because stream may be glued from different streams
                    if (code == MP4_VISUAL_OBJECT_SEQUENCE_SC) {
                        if (mp4_Parse_VisualObjectSequence(m_decInfo) != MP4_STATUS_OK) {
                            status = UMC_ERR_INVALID_STREAM;
                            break;
                        }
                    } else if (code == MP4_VISUAL_OBJECT_SC) {
                        if (mp4_Parse_VisualObject(m_decInfo) != MP4_STATUS_OK) {
                            status = UMC_ERR_INVALID_STREAM;
                            break;
                        }
                    } else if (code >= MP4_VIDEO_OBJECT_LAYER_MIN_SC && code <= MP4_VIDEO_OBJECT_LAYER_MAX_SC) {
                        // in repeated headers check only VOL header
                        m_decInfo->bufptr -= 4;
                        // save parameters which can affect on reinit
                        Ipp32s interlaced = m_decInfo->VisualObject.VideoObject.interlaced;
                        Ipp32s data_partitioned = m_decInfo->VisualObject.VideoObject.data_partitioned;
                        Ipp32s sprite_enable = m_decInfo->VisualObject.VideoObject.sprite_enable;
                        Ipp32s width = m_decInfo->VisualObject.VideoObject.width;
                        Ipp32s height = m_decInfo->VisualObject.VideoObject.height;
                        if (mp4_Parse_VideoObject(m_decInfo) != MP4_STATUS_OK) {
                            status = UMC_ERR_INVALID_STREAM;
                            break;
                        }
                        // realloc if something was changed
                        if (interlaced != m_decInfo->VisualObject.VideoObject.interlaced ||
                            data_partitioned != m_decInfo->VisualObject.VideoObject.data_partitioned ||
                            sprite_enable != m_decInfo->VisualObject.VideoObject.sprite_enable ||
                            width != m_decInfo->VisualObject.VideoObject.width ||
                            height != m_decInfo->VisualObject.VideoObject.height) {
                            if (width != m_decInfo->VisualObject.VideoObject.width ||
                                height != m_decInfo->VisualObject.VideoObject.height) {
                                m_Param.info.clip_info.width = m_decInfo->VisualObject.VideoObject.width;
                                m_Param.info.clip_info.height = m_decInfo->VisualObject.VideoObject.height;
                            }
                            UnlockBuffers();
                            status = FreeBuffers();
                            if (status != UMC_OK)
                                break;
                            status = AllocateBuffers();
                            if (status != UMC_OK)
                                break;
                            LockBuffers();
                            // free buffers for MPEG-4 post-processing
                            if (ppFrame0.mid) {
                                status = m_pMemoryAllocator->Free(ppFrame0.mid);
                                ppFrame0.mid = 0;
                                if (status != UMC_OK)
                                    break;
                            }
                            if (ppFrame1.mid) {
                                status = m_pMemoryAllocator->Free(ppFrame1.mid);
                                ppFrame1.mid = 0;
                                if (status != UMC_OK)
                                    break;
                            }
                            // will be allocated before processing
                        } else
                            if (m_decInfo->strictSyntaxCheck) {
                                mp4_Error("Error: Repeated VOL header is different from previous");
                                status = UMC_ERR_INVALID_STREAM;
                                break;
                            }
                        // reinit quant matrix
                        ippiQuantInvIntraInit_MPEG4(m_decInfo->VisualObject.VideoObject.quant_type ? m_decInfo->VisualObject.VideoObject.intra_quant_mat : NULL, m_decInfo->VisualObject.VideoObject.QuantInvIntraSpec, 8);
                        ippiQuantInvInterInit_MPEG4(m_decInfo->VisualObject.VideoObject.quant_type ? m_decInfo->VisualObject.VideoObject.nonintra_quant_mat : NULL, m_decInfo->VisualObject.VideoObject.QuantInvInterSpec, 8);
                    } else if (code == MP4_GROUP_OF_VOP_SC) {
                        if (mp4_Parse_GroupOfVideoObjectPlane(m_decInfo) != MP4_STATUS_OK) {
                            status = UMC_ERR_INVALID_STREAM;
                            break;
                        }
                    } else if (m_decInfo->bufptr[-1] == MP4_VIDEO_OBJECT_PLANE_SC) {
                        break;
                    }
                }
                if (status != UMC_OK)
                    break;
            }
            // parse VOP header
            if ((mp4_Parse_VideoObjectPlane(m_decInfo)) != MP4_STATUS_OK) {
                status = UMC_WRN_INVALID_STREAM;
                break;
            }
            if (m_IsReset && m_decInfo->VisualObject.VideoObject.VideoObjectPlane.coding_type != MP4_VOP_TYPE_I) {
                return UMC_ERR_NOT_ENOUGH_DATA;
                break;
            }
            if (m_decInfo->VisualObject.VideoObject.VideoObjectPlane.coding_type == MP4_VOP_TYPE_B) {
                if (0 < m_is_skipped_b && !m_b_prev) {
                    m_is_skipped_b --;
                    m_skipped_fr ++;
                    m_b_prev = 1;
                    m_decInfo->bufptr = m_decInfo->buffer+ m_decInfo->buflen;
                    status = UMC_ERR_NOT_ENOUGH_DATA;
                    break;
                } else
                    m_b_prev = 0;
            }
            // decode VOP
            if ((mp4_DecodeVideoObjectPlane(m_decInfo)) != MP4_STATUS_OK) {
                status = UMC_WRN_INVALID_STREAM;
            }
            // after reset it is need to skip first B-frames
            if (m_decInfo->VisualObject.VideoObject.VOPindex < 2 && m_decInfo->VisualObject.VideoObject.VideoObjectPlane.coding_type == MP4_VOP_TYPE_B) {
                status = UMC_ERR_NOT_ENOUGH_DATA;
                break;
            }
            // do not count not_coded P frames with same vop_time as reference (in AVI)
            if (m_decInfo->VisualObject.VideoObject.VideoObjectPlane.coded ||
                (m_decInfo->VisualObject.rFrame.time != m_decInfo->VisualObject.cFrame.time &&
                 m_decInfo->VisualObject.nFrame.time != m_decInfo->VisualObject.cFrame.time)) {
                m_decInfo->VisualObject.VideoObject.VOPindex++;

            } else {
                status = UMC_ERR_NOT_ENOUGH_DATA;
                break;
            }
            if (m_IsReset && m_decInfo->VisualObject.VideoObject.VideoObjectPlane.coding_type == MP4_VOP_TYPE_I) {
                m_time_reset = (Ipp32s)m_decInfo->VisualObject.cFrame.time;
                m_decInfo->VisualObject.vFrame = NULL;
                m_IsReset = false;
            }
            if ((m_Param.lFlags & FLAG_VDEC_REORDER) && (m_decInfo->VisualObject.vFrame == NULL)) {
                // buffer first frame in VDEC_REORDER mode
                status = UMC_ERR_NOT_ENOUGH_DATA;
                break;
            }
            if (!(m_Param.lFlags & FLAG_VDEC_REORDER))
                m_decInfo->VisualObject.vFrame = &m_decInfo->VisualObject.cFrame;
        }
        break;
    }
    if (in)
        if (in->GetTime() != -1.0 && m_dec_time_base == -1.0)
            m_dec_time_base = in->GetTime();
    if ((m_dec_time_frinc > 0.0) || (m_decInfo->ftype == 1)) {
        if (m_Param.lFlags & FLAG_VDEC_REORDER)
            pts = m_dec_time_prev;
        if (in) {
            if (in->GetTime() != -1.0) {
                // take right PTS for I-, P- frames
                m_dec_time_prev = in->GetTime();
            } else {
                // when PB...  are in one AVI chunk, first PTS from in->GetTime() is right and second is -1.0
                m_dec_time_prev += m_dec_time_frinc;
            }
        }
        if (!(m_Param.lFlags & FLAG_VDEC_REORDER))
            pts = m_dec_time_prev;
    } else {
        bool  extPTS = false;
        if (in)
            if (in->GetTime() != -1.0)
                extPTS = true;
        if (extPTS) {
            pts = in->GetTime();
        } else {
            // for other internal MPEG-4 PTS is used
            if (m_decInfo->VisualObject.vFrame)
                pts = (Ipp64f)(m_decInfo->VisualObject.vFrame->time - m_time_reset) / m_decInfo->VisualObject.VideoObject.vop_time_increment_resolution;
            else {
                pts = 0.0;
            }
            if (m_dec_time_base != -1.0)
                pts += m_dec_time_base;
        }
    }
    if ((UMC_OK == status || UMC_WRN_INVALID_STREAM == status) && (m_decInfo->VisualObject.vFrame != NULL)) {
        FrameType ft;
        if (m_decInfo->VisualObject.VideoObject.sprite_enable == MP4_SPRITE_STATIC)
            ft = I_PICTURE;
        else
            ft = (m_decInfo->VisualObject.vFrame->type) == MP4_VOP_TYPE_I ? I_PICTURE :
                 (m_decInfo->VisualObject.vFrame->type) == MP4_VOP_TYPE_B ? B_PICTURE :
                                                                            P_PICTURE;
        mp4_Frame rendFrame = *m_decInfo->VisualObject.vFrame;
        bool     ppDeblocking = m_DeblockingProcPlane[0] || m_DeblockingProcPlane[1] || m_DeblockingProcPlane[2];
        bool     ppDeringing = m_DeringingProcPlane[0] || m_DeringingProcPlane[1] || m_DeringingProcPlane[2];

        if (ppDeblocking || ppDeringing) {
            if (!ppFrame0.mid) {
                ppFrame0.mbPerRow = m_decInfo->VisualObject.vFrame->mbPerRow;
                ppFrame0.mbPerCol = m_decInfo->VisualObject.vFrame->mbPerCol;
                status = AllocateInitFrame(&ppFrame0);
                if (status != UMC_OK)
                    return status;
            }
            if (!ppFrame1.mid) {
                ppFrame1.mbPerRow = m_decInfo->VisualObject.vFrame->mbPerRow;

⌨️ 快捷键说明

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