static void emit_frame(vda_decoder_t *vdad, vda_frame_t *vf, media_queue_t *mq) { int i; CGSize siz; frame_info_t fi; memset(&fi, 0, sizeof(fi)); CVPixelBufferLockBaseAddress(vf->vf_buf, 0); for(i = 0; i < 3; i++ ) { fi.fi_data[i] = CVPixelBufferGetBaseAddressOfPlane(vf->vf_buf, i); fi.fi_pitch[i] = CVPixelBufferGetBytesPerRowOfPlane(vf->vf_buf, i); } if(vdad->vdad_last_pts != PTS_UNSET && vf->vf_pts != PTS_UNSET) { int64_t d = vf->vf_pts - vdad->vdad_last_pts; if(d > 1000 && d < 1000000) vdad->vdad_estimated_duration = d; } siz = CVImageBufferGetEncodedSize(vf->vf_buf); fi.fi_type = 'YUVP'; fi.fi_width = siz.width; fi.fi_height = siz.height; fi.fi_duration = vf->vf_duration > 10000 ? vf->vf_duration : vdad->vdad_estimated_duration; siz = CVImageBufferGetDisplaySize(vf->vf_buf); fi.fi_dar_num = siz.width; fi.fi_dar_den = siz.height; fi.fi_pts = vf->vf_pts; fi.fi_color_space = -1; fi.fi_epoch = vf->vf_epoch; fi.fi_drive_clock = 1; fi.fi_vshift = 1; fi.fi_hshift = 1; video_decoder_t *vd = vdad->vdad_vd; vd->vd_estimated_duration = fi.fi_duration; // For bitrate calculations if(fi.fi_duration > 0) video_deliver_frame(vd, &fi); CVPixelBufferUnlockBaseAddress(vf->vf_buf, 0); vdad->vdad_last_pts = vf->vf_pts; char fmt[64]; snprintf(fmt, sizeof(fmt), "h264 (VDA) %d x %d", fi.fi_width, fi.fi_height); prop_set_string(mq->mq_prop_codec, fmt); }
static void emit_frame(vtb_decoder_t *vtbd, vtb_frame_t *vf, media_queue_t *mq) { CGSize siz; frame_info_t fi; memset(&fi, 0, sizeof(fi)); if(vtbd->vtbd_last_pts != PTS_UNSET && vf->vf_mbm.mbm_pts != PTS_UNSET) { int64_t d = vf->vf_mbm.mbm_pts - vtbd->vtbd_last_pts; if(d > 1000 && d < 1000000) vtbd->vtbd_estimated_duration = d; } siz = CVImageBufferGetDisplaySize(vf->vf_buf); fi.fi_dar_num = siz.width; fi.fi_dar_den = siz.height; fi.fi_pts = vf->vf_mbm.mbm_pts; fi.fi_color_space = -1; fi.fi_epoch = vf->vf_mbm.mbm_epoch; fi.fi_drive_clock = vf->vf_mbm.mbm_drive_clock; fi.fi_user_time = vf->vf_mbm.mbm_user_time; fi.fi_vshift = 1; fi.fi_hshift = 1; fi.fi_duration = vf->vf_mbm.mbm_duration > 10000 ? vf->vf_mbm.mbm_duration : vtbd->vtbd_estimated_duration; siz = CVImageBufferGetEncodedSize(vf->vf_buf); fi.fi_width = siz.width; fi.fi_height = siz.height; video_decoder_t *vd = vtbd->vtbd_vd; vd->vd_estimated_duration = fi.fi_duration; // For bitrate calculations switch(vtbd->vtbd_pixel_format) { case kCVPixelFormatType_420YpCbCr8Planar: fi.fi_type = 'YUVP'; CVPixelBufferLockBaseAddress(vf->vf_buf, 0); for(int i = 0; i < 3; i++ ) { fi.fi_data[i] = CVPixelBufferGetBaseAddressOfPlane(vf->vf_buf, i); fi.fi_pitch[i] = CVPixelBufferGetBytesPerRowOfPlane(vf->vf_buf, i); } if(fi.fi_duration > 0) video_deliver_frame(vd, &fi); CVPixelBufferUnlockBaseAddress(vf->vf_buf, 0); break; case kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange: case kCVPixelFormatType_420YpCbCr8BiPlanarFullRange: fi.fi_type = 'CVPB'; fi.fi_data[0] = (void *)vf->vf_buf; if(fi.fi_duration > 0) video_deliver_frame(vd, &fi); break; } vtbd->vtbd_last_pts = vf->vf_mbm.mbm_pts; char fmt[64]; snprintf(fmt, sizeof(fmt), "h264 (VTB) %d x %d", fi.fi_width, fi.fi_height); prop_set_string(mq->mq_prop_codec, fmt); }