static int vda_h264_end_frame(AVCodecContext *avctx) { H264Context *h = avctx->priv_data; VDAContext *vda = avctx->internal->hwaccel_priv_data; AVVDAContext *vda_ctx = avctx->hwaccel_context; AVFrame *frame = h->cur_pic_ptr->f; uint32_t flush_flags = 1 << 0; ///< kVDADecoderFlush_emitFrames CFDataRef coded_frame; OSStatus status; if (!vda->bitstream_size) return AVERROR_INVALIDDATA; coded_frame = CFDataCreate(kCFAllocatorDefault, vda->bitstream, vda->bitstream_size); status = VDADecoderDecode(vda_ctx->decoder, 0, coded_frame, NULL); if (status == kVDADecoderNoErr) status = VDADecoderFlush(vda_ctx->decoder, flush_flags); CFRelease(coded_frame); if (!vda->frame) return AVERROR_UNKNOWN; if (status != kVDADecoderNoErr) { av_log(avctx, AV_LOG_ERROR, "Failed to decode frame (%d)\n", status); return AVERROR_UNKNOWN; } av_buffer_unref(&frame->buf[0]); frame->buf[0] = av_buffer_create((uint8_t*)vda->frame, sizeof(vda->frame), release_buffer, NULL, AV_BUFFER_FLAG_READONLY); if (!frame->buf[0]) return AVERROR(ENOMEM); frame->data[3] = (uint8_t*)vda->frame; vda->frame = NULL; return 0; }
static int vda_decoder_decode(struct vda_context *vda_ctx, uint8_t *bitstream, int bitstream_size, int64_t frame_pts) { OSStatus status = kVDADecoderNoErr; CFDictionaryRef user_info; CFDataRef coded_frame; coded_frame = CFDataCreate(kCFAllocatorDefault, bitstream, bitstream_size); user_info = vda_dictionary_with_pts(frame_pts); status = VDADecoderDecode(vda_ctx->decoder, 0, coded_frame, user_info); CFRelease(user_info); CFRelease(coded_frame); return status; }
static int vda_sync_decode(struct vda_context *vda_ctx) { OSStatus status; CFDataRef coded_frame; uint32_t flush_flags = 1 << 0; ///< kVDADecoderFlush_emitFrames coded_frame = CFDataCreate(kCFAllocatorDefault, vda_ctx->priv_bitstream, vda_ctx->priv_bitstream_size); status = VDADecoderDecode(vda_ctx->decoder, 0, coded_frame, NULL); if (kVDADecoderNoErr == status) status = VDADecoderFlush(vda_ctx->decoder, flush_flags); CFRelease(coded_frame); return status; }
void MoonVDADecoder::DecodeFrameAsyncInternal (MediaFrame *mf) { CFDictionaryValueCallBacks valueCallbacks = {0, 0, 0, 0, 0}; CFMutableDictionaryRef frameInfo = CFDictionaryCreateMutable (kCFAllocatorDefault, 1, &kCFTypeDictionaryKeyCallBacks, &valueCallbacks); CFDataRef compressedBuffer = CFDataCreate (kCFAllocatorDefault, (const uint8_t*) mf->GetBuffer (), mf->GetBufLen ()); CFDictionarySetValue (frameInfo, CFSTR ("MoonMediaFrame"), mf); OSStatus status = VDADecoderDecode (decoder, 0, compressedBuffer, frameInfo); if (status != kVDADecoderNoErr) { g_warning ("VDADecoderDecode returned: %i\n", status); } if (compressedBuffer) CFRelease (compressedBuffer); if (frameInfo) CFRelease (frameInfo); mf->ref (); }
int CDVDVideoCodecVDA::Decode(uint8_t* pData, int iSize, double dts, double pts) { CCocoaAutoPool pool; // if (pData) { m_bitstream->Convert(pData, iSize); CFDataRef avc_demux = CFDataCreate(kCFAllocatorDefault, m_bitstream->GetConvertBuffer(), m_bitstream->GetConvertSize()); CFDictionaryRef avc_time = CreateDictionaryWithDisplayTime(m_sort_time++, dts, pts); uint32_t avc_flags = 0; if (m_DropPictures) avc_flags = kVDADecoderDecodeFlags_DontEmitFrame; OSStatus status = VDADecoderDecode((VDADecoder)m_vda_decoder, avc_flags, avc_demux, avc_time); CFRelease(avc_time); CFRelease(avc_demux); if (status != kVDADecoderNoErr) { CLog::Log(LOGNOTICE, "%s - VDADecoderDecode failed, status(%d)", __FUNCTION__, (int)status); return VC_ERROR; } } if (!m_decode_async) { // force synchronous decode to fix issues with ATI GPUs, // we still have to sort returned frames by pts to handle out-of-order demuxer packets. VDADecoderFlush((VDADecoder)m_vda_decoder, kVDADecoderFlush_EmitFrames); } if (m_queue_depth < m_max_ref_frames) return VC_BUFFER; return VC_PICTURE; }
nsresult AppleVDADecoder::SubmitFrame(mp4_demuxer::MP4Sample* aSample) { AutoCFRelease<CFDataRef> block = CFDataCreate(kCFAllocatorDefault, aSample->data, aSample->size); if (!block) { NS_ERROR("Couldn't create CFData"); return NS_ERROR_FAILURE; } AutoCFRelease<CFNumberRef> pts = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &aSample->composition_timestamp); AutoCFRelease<CFNumberRef> dts = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &aSample->decode_timestamp); AutoCFRelease<CFNumberRef> duration = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &aSample->duration); AutoCFRelease<CFNumberRef> byte_offset = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &aSample->byte_offset); char keyframe = aSample->is_sync_point ? 1 : 0; AutoCFRelease<CFNumberRef> cfkeyframe = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt8Type, &keyframe); const void* keys[] = { CFSTR("FRAME_PTS"), CFSTR("FRAME_DTS"), CFSTR("FRAME_DURATION"), CFSTR("FRAME_OFFSET"), CFSTR("FRAME_KEYFRAME") }; const void* values[] = { pts, dts, duration, byte_offset, cfkeyframe }; static_assert(ArrayLength(keys) == ArrayLength(values), "Non matching keys/values array size"); AutoCFRelease<CFDictionaryRef> frameInfo = CFDictionaryCreate(kCFAllocatorDefault, keys, values, ArrayLength(keys), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); OSStatus rv = VDADecoderDecode(mDecoder, 0, block, frameInfo); if (rv != noErr) { NS_WARNING("AppleVDADecoder: Couldn't pass frame to decoder"); return NS_ERROR_FAILURE; } if (mIs106) { // TN2267: // frameInfo: A CFDictionaryRef containing information to be returned in // the output callback for this frame. // This dictionary can contain client provided information associated with // the frame being decoded, for example presentation time. // The CFDictionaryRef will be retained by the framework. // In 10.6, it is released one too many. So retain it. CFRetain(frameInfo); } // Ask for more data. if (mTaskQueue->IsEmpty()) { LOG("AppleVDADecoder task queue empty; requesting more data"); mCallback->InputExhausted(); } return NS_OK; }
static void vda_decode(struct media_codec *mc, struct video_decoder *vd, struct media_queue *mq, struct media_buf *mb, int reqsize) { vda_decoder_t *vdad = mc->opaque; CFDictionaryRef user_info; CFDataRef coded_frame; const int num_kvs = 6; CFStringRef keys[num_kvs]; CFNumberRef values[num_kvs]; const int keyframe = mb->mb_keyframe; const int drive_clock = mb->mb_drive_clock; vda_frame_t *vf; int i; uint8_t skip = mb->mb_skip; vdad->vdad_vd = vd; coded_frame = CFDataCreate(kCFAllocatorDefault, mb->mb_data, mb->mb_size); keys[0] = CFSTR("pts"); keys[1] = CFSTR("duration"); keys[2] = CFSTR("keyframe"); keys[3] = CFSTR("epoch"); keys[4] = CFSTR("drive_clock"); keys[5] = CFSTR("skip"); values[0] = CFNumberCreate(NULL, kCFNumberSInt64Type, &mb->mb_pts); values[1] = CFNumberCreate(NULL, kCFNumberSInt32Type, &mb->mb_duration); values[2] = CFNumberCreate(NULL, kCFNumberSInt32Type, &keyframe); values[3] = CFNumberCreate(NULL, kCFNumberSInt8Type, &mb->mb_epoch); values[4] = CFNumberCreate(NULL, kCFNumberSInt8Type, &drive_clock); values[5] = CFNumberCreate(NULL, kCFNumberSInt8Type, &skip); user_info = CFDictionaryCreate(kCFAllocatorDefault, (const void **)keys, (const void **)values, num_kvs, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); for(i = 0; i < num_kvs; i++) CFRelease(values[i]); uint32_t flags = 0; VDADecoderDecode(vdad->vdad_decoder, flags, coded_frame, user_info); CFRelease(user_info); CFRelease(coded_frame); hts_mutex_lock(&vdad->vdad_mutex); if(vdad->vdad_flush_to != PTS_UNSET) { while((vf = LIST_FIRST(&vdad->vdad_frames)) != NULL) { if(vdad->vdad_flush_to < vf->vf_pts) break; LIST_REMOVE(vf, vf_link); hts_mutex_unlock(&vdad->vdad_mutex); emit_frame(vdad, vf, mq); hts_mutex_lock(&vdad->vdad_mutex); CFRelease(vf->vf_buf); free(vf); } } hts_mutex_unlock(&vdad->vdad_mutex); }