H264Context *h = avctx->priv_data;
CFDataRef data = NULL;
uint8_t *p;
- int vt_extradata_size = 6 + 3 + h->ps.sps->data_size + 4 + h->ps.sps->data_size;
+ int vt_extradata_size = 6 + 3 + h->ps.sps->data_size + 4 + h->ps.pps->data_size;
uint8_t *vt_extradata = av_malloc(vt_extradata_size);
if (!vt_extradata)
return NULL;
memcpy(p + 9, h->ps.sps->data, h->ps.sps->data_size);
p += 9 + h->ps.sps->data_size;
AV_W8(p + 0, 1); /* number of pps */
- AV_WB16(p + 1, h->pps.data_size + 1);
+ AV_WB16(p + 1, h->ps.pps->data_size + 1);
AV_W8(p + 3, NAL_PPS | (3 << 5)); // NAL unit header
- memcpy(p + 4, h->pps.data, h->pps.data_size);
+ memcpy(p + 4, h->ps.pps->data, h->ps.pps->data_size);
- p += 4 + h->pps.data_size;
+ p += 4 + h->ps.pps->data_size;
av_assert0(p - vt_extradata == vt_extradata_size);
data = CFDataCreate(kCFAllocatorDefault, vt_extradata, vt_extradata_size);
AVCodecContext *avctx)
{
CFMutableDictionaryRef config_info = CFDictionaryCreateMutable(kCFAllocatorDefault,
- 1,
+ 0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
return buffer_attributes;
}
-static CMVideoFormatDescriptionRef videotoolbox_format_desc_create(CMVideoCodecType codec_type,
+static CMVideoFormatDescriptionRef videotoolbox_format_desc_create(AVCodecContext *avctx,
+ CMVideoCodecType codec_type,
CFDictionaryRef decoder_spec,
int width,
int height)
{
- CMFormatDescriptionRef cm_fmt_desc;
- OSStatus status;
+ CMFormatDescriptionRef cm_fmt_desc = NULL;
+ int status;
- status = CMVideoFormatDescriptionCreate(kCFAllocatorDefault,
- codec_type,
- width,
- height,
- decoder_spec, // Dictionary of extension
- &cm_fmt_desc);
+#if TARGET_OS_IPHONE || defined(__MAC_10_9)
+ H264Context *h = codec_type == kCMVideoCodecType_H264 ? avctx->priv_data : NULL;
- if (status)
- return NULL;
+ if (h && h->ps.sps->data_size && h->ps.pps->data_size) {
+ int ps_count = 2;
+ const uint8_t **ps_data = av_malloc(sizeof(uint8_t*) * ps_count);
+ size_t *ps_sizes = av_malloc(sizeof(size_t) * ps_count);
+
+ ps_data[0] = h->ps.sps->data;
+ ps_sizes[0] = h->ps.sps->data_size;
+
+ ps_data[1] = h->ps.pps->data;
+ ps_sizes[1] = h->ps.pps->data_size;
+
+ status = CMVideoFormatDescriptionCreateFromH264ParameterSets(NULL,
+ ps_count,
+ ps_data,
+ ps_sizes,
+ 4,
+ &cm_fmt_desc);
+ av_freep(&ps_sizes);
+ av_freep(&ps_data);
+
+ if (status) {
+ av_log(avctx, AV_LOG_ERROR, "Error creating H.264 format description: %d\n", status);
+ return NULL;
+ }
+ } else {
+#endif
+ status = CMVideoFormatDescriptionCreate(kCFAllocatorDefault,
+ codec_type,
+ width,
+ height,
+ decoder_spec, // Dictionary of extension
+ &cm_fmt_desc);
+
+ if (status) {
+ av_log(avctx, AV_LOG_ERROR, "Error creating format description: %d\n", status);
+ return NULL;
+ }
+#if TARGET_OS_IPHONE || defined(__MAC_10_9)
+ }
+#endif
return cm_fmt_desc;
}
decoder_spec = videotoolbox_decoder_config_create(videotoolbox->cm_codec_type, avctx);
- videotoolbox->cm_fmt_desc = videotoolbox_format_desc_create(videotoolbox->cm_codec_type,
+ videotoolbox->cm_fmt_desc = videotoolbox_format_desc_create(avctx,
+ videotoolbox->cm_codec_type,
decoder_spec,
avctx->width,
avctx->height);
if (videotoolbox->cm_fmt_desc)
CFRelease(videotoolbox->cm_fmt_desc);
- if (videotoolbox->session)
+ if (videotoolbox->session) {
VTDecompressionSessionInvalidate(videotoolbox->session);
+ CFRelease(videotoolbox->session);
+ }
}
}