📄 mpeg4.cpp
字号:
buffer[buflen + 2] = 1; switch (iso->m_decodeState) { case DECODE_STATE_VOL_SEARCH: { if (buffer[0] == 0 && buffer[1] == 0 && (buffer[2] & 0xfc) == 0x80 && (buffer[3] & 0x03) == 0x02) { // we have the short header iso->m_short_header = 1; iso->m_pvodec->SetUpBitstreamBuffer((unsigned char *)buffer, buflen); iso->m_pvodec->video_plane_with_short_header(); iso->m_pvodec->postVO_VOLHeadInit(iso->m_pvodec->getWidth(), iso->m_pvodec->getHeight(), &iso->m_bSpatialScalability); iso_message(LOG_INFO, mp4iso, "Decoding using short headers"); iso->m_vft->video_configure(iso->m_ifptr, iso->m_pvodec->getWidth(), iso->m_pvodec->getHeight(), VIDEO_FORMAT_YUV, calculate_aspect_ratio(iso)); iso->m_decodeState = DECODE_STATE_NORMAL; try { iEof = iso->m_pvodec->h263_decode(FALSE); } catch (...) { iso_message(LOG_ERR, mp4iso, "Couldn't decode h263 in vol search"); } break; } else { uint8_t *volhdr = MP4AV_Mpeg4FindVol(buffer, buflen); if (volhdr != NULL) { used = volhdr - buffer; try { iso->m_pvodec->SetUpBitstreamBuffer((unsigned char *)volhdr, buflen - used); iso->m_pvodec->decodeVOLHead(); iso->m_pvodec->postVO_VOLHeadInit(iso->m_pvodec->getWidth(), iso->m_pvodec->getHeight(), &iso->m_bSpatialScalability); iso_message(LOG_INFO, mp4iso, "Found VOL"); iso->m_vft->video_configure(iso->m_ifptr, iso->m_pvodec->getWidth(), iso->m_pvodec->getHeight(), VIDEO_FORMAT_YUV, calculate_aspect_ratio(iso)); iso->m_decodeState = DECODE_STATE_WAIT_I; used += iso->m_pvodec->get_used_bytes(); } catch (int err) { iso_message(LOG_DEBUG, mp4iso, "Caught exception in VOL search %d", err); if (err == 1) used = buflen; else used += iso->m_pvodec->get_used_bytes(); } } } if (iso->m_decodeState != DECODE_STATE_WAIT_I) { if (iso->m_vinfo != NULL) { iso->m_pvodec->FakeOutVOVOLHead(iso->m_vinfo->height, iso->m_vinfo->width, 30, &iso->m_bSpatialScalability); iso->m_vft->video_configure(iso->m_ifptr, iso->m_vinfo->width, iso->m_vinfo->height, VIDEO_FORMAT_YUV, calculate_aspect_ratio(iso)); iso->m_decodeState = DECODE_STATE_NORMAL; } return used; } // else fall through } case DECODE_STATE_WAIT_I: { uint8_t *vophdr = MP4AV_Mpeg4FindVop(buffer, buflen); if (vophdr != NULL) { used = vophdr - buffer; } iso->m_pvodec->SetUpBitstreamBuffer((unsigned char *)buffer + used, buflen + 3 - used); try { iEof = iso->m_pvodec->decode(NULL, TRUE); if (iEof == -1) { iso->m_num_wait_i_frames++; return(iso->m_pvodec->get_used_bytes()); } iso_message(LOG_DEBUG, mp4iso, "Back to normal decode"); iso->m_decodeState = DECODE_STATE_NORMAL; iso->m_bCachedRefFrame = FALSE; iso->m_bCachedRefFrameCoded = FALSE; iso->m_cached_valid = FALSE; iso->m_cached_time = 0; } catch (int err) { if (err != 1) iso_message(LOG_DEBUG, mp4iso, "ts "U64",Caught exception in wait_i %d", ts->msec_timestamp, err); return (iso->m_pvodec->get_used_bytes()); //return (-1); } break; } case DECODE_STATE_NORMAL: try { if (iso->m_short_header != 0) { iso->m_pvodec->SetUpBitstreamBuffer((unsigned char *)buffer, buflen + 3); iEof = iso->m_pvodec->h263_decode(TRUE); } else { uint8_t *vophdr = MP4AV_Mpeg4FindVop(buffer, buflen); if (vophdr != NULL && vophdr != buffer) { iso_message(LOG_DEBUG, mp4iso, "Illegal code before VOP header"); used = vophdr - buffer; buflen -= used; buffer = vophdr; } iso->m_pvodec->SetUpBitstreamBuffer((unsigned char *)buffer, buflen + 3); iEof = iso->m_pvodec->decode(NULL, FALSE, FALSE); } } catch (int err) { // This is because sometimes, the encoder doesn't read all the bytes // it should out of the rtp packet. The rtp bytestream does a read // and determines that we're trying to read across bytestreams. // If we get this, we don't want to change anything - just fall up // to the decoder thread so it gives us a new timestamp. if (err == 1) { // throw from running past end of frame return -1; } iso_message(LOG_DEBUG, mp4iso, "Mpeg4 ncaught %d -> waiting for I", err); iso->m_decodeState = DECODE_STATE_WAIT_I; return (iso->m_pvodec->get_used_bytes()); } catch (...) { iso_message(LOG_DEBUG, mp4iso, "Mpeg4 ncaught -> waiting for I"); iso->m_decodeState = DECODE_STATE_WAIT_I; //return (-1); return (iso->m_pvodec->get_used_bytes()); } break; } /* * We've got a good frame. See if we need to display it */ const CVOPU8YUVBA *pvopcQuant = NULL; if (iso->m_pvodec->fSptUsage() == 1) { //player_debug_message("Sprite"); } uint64_t displaytime = 0; int cached_ts = 0; if (iEof == EOF) { if (iso->m_bCachedRefFrame) { iso->m_bCachedRefFrame = FALSE; if (iso->m_bCachedRefFrameCoded) { pvopcQuant = iso->m_pvodec->pvopcRefQLater(); displaytime = ts->msec_timestamp; } } } else {#if 0 iso_message(LOG_DEBUG, mp4iso, "frame "U64" type %d", ts->msec_timestamp, iso->m_pvodec->vopmd().vopPredType);#endif if (iso->m_pvodec->vopmd().vopPredType == BVOP) { if (iEof != FALSE) { pvopcQuant = iso->m_pvodec->pvopcReconCurr(); displaytime = ts->msec_timestamp; } } else { if (iso->m_bCachedRefFrame) { iso->m_bCachedRefFrame = FALSE; if (iso->m_bCachedRefFrameCoded) { pvopcQuant = iso->m_pvodec->pvopcRefQPrev(); if (ts->timestamp_is_pts) { int old_was_valid = iso->m_cached_valid; displaytime = iso->m_cached_time; cached_ts = 1; // old time stamp wasn't valid - instead of calculating it // ourselves, just punt on it. if (old_was_valid == 0) { return (iEof == EOF ? -1 : 0); } } else { displaytime = ts->msec_timestamp; } } } iso->m_cached_time = ts->msec_timestamp; iso->m_cached_valid = TRUE; iso->m_bCachedRefFrame = TRUE; iso->m_bCachedRefFrameCoded = (iEof != FALSE); } } if (pvopcQuant != NULL) {#if 0 player_debug_message("frame rtp_ts "U64" disp "U64" cached %d", ts->msec_timestamp, displaytime, cached_ts);#endif /* * Get the information to the video sync structure */ const uint8_t *y, *u, *v; int pixelw_y, pixelw_uv; pixelw_y = pvopcQuant->getPlane(Y_PLANE)->where().width; pixelw_uv = pvopcQuant->getPlane(U_PLANE)->where().width; y = (const uint8_t *)pvopcQuant->getPlane(Y_PLANE)->pixels(0,0); u = (const uint8_t *)pvopcQuant->getPlane(U_PLANE)->pixels(0,0); v = (const uint8_t *)pvopcQuant->getPlane(V_PLANE)->pixels(0,0); iso->m_last_time = displaytime;#if 0 player_debug_message("Adding video at "U64" %d", displaytime, iso->m_pvodec->vopmd().vopPredType);#endif iso->m_vft->video_have_frame(iso->m_ifptr, y, u, v, pixelw_y, pixelw_uv, displaytime); } else { iso_message(LOG_DEBUG, mp4iso, "decode but no frame "U64, ts->msec_timestamp); } return (iso->m_pvodec->get_used_bytes() + used);}static int iso_skip_frame (codec_data_t *iso){#if 0 return (iso_decode(iso, ts, 0, NULL, buffer, buflen));#else return 0;#endif}static const char *iso_compressors[] = { "mp4 ", "mp4v", "encv", "divx", "dvx1", "div4", "mpeg4", "xvid", NULL,};static int iso_codec_check (lib_message_func_t message, const char *stream_type, const char *compressor, int type, int profile, format_list_t *fptr, const uint8_t *userdata, uint32_t userdata_size, CConfigSet *pConfig){ int ret_val = -1; if (strcasecmp(stream_type, STREAM_TYPE_MP4_FILE) == 0) { if (strcasecmp(compressor, "mp4v") == 0 || strcasecmp(compressor, "encv") == 0 && (type == MP4_MPEG4_VIDEO_TYPE || type == MP4_H263_VIDEO_TYPE)) { ret_val = 1; } } if (strcasecmp(stream_type, STREAM_TYPE_RTP) == 0 && fptr != NULL) { // find format. If matches, call parse_fmtp_for_mpeg4, look at // profile level.#if 1 if (strcmp(fptr->fmt, "34") == 0) { ret_val = 1; }#endif if (fptr->rtpmap_name != NULL) { if (strcasecmp(fptr->rtpmap_name, "MP4V-ES") == 0 || strcasecmp(fptr->rtpmap_name, "enc-mpeg4-generic") == 0) { ret_val = 1; } } } if (compressor != NULL) { const char **lptr = iso_compressors; while (*lptr != NULL) { if (strcasecmp(*lptr, compressor) == 0) { ret_val = 1; break; } lptr++; } } if (ret_val == 1 && pConfig->GetBoolValue(CONFIG_USE_MPEG4_ISO_ONLY)) { ret_val = 255; message(LOG_DEBUG, "mpeg4iso", "Asserting mpeg4 iso only"); } return ret_val;}VIDEO_CODEC_WITH_RAW_FILE_PLUGIN("MPEG4 ISO", iso_create, iso_do_pause, iso_decode, NULL, iso_close, iso_codec_check, iso_frame_is_sync, mpeg4_iso_file_check, divx_file_next_frame, divx_file_used_for_frame, divx_file_seek_to, iso_skip_frame, divx_file_eof, MyConfigVariables, sizeof(MyConfigVariables) / sizeof(*MyConfigVariables));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -