Example #1
0
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;
}
Example #2
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;
}
Example #3
0
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;
}
Example #4
0
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 ();
}
Example #5
0
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;
}
Example #7
0
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);
}