2 * - CrystalHD decoder module -
4 * Copyright(C) 2010,2011 Philip Langdale <ffmpeg.philipl@overt.org>
6 * This file is part of FFmpeg.
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 * - Principles of Operation -
26 * The CrystalHD decoder operates at the bitstream level - which is an even
27 * higher level than the decoding hardware you typically see in modern GPUs.
28 * This means it has a very simple interface, in principle. You feed demuxed
29 * packets in one end and get decoded picture (fields/frames) out the other.
31 * Of course, nothing is ever that simple. Due, at the very least, to b-frame
32 * dependencies in the supported formats, the hardware has a delay between
33 * when a packet goes in, and when a picture comes out. Furthermore, this delay
34 * is not just a function of time, but also one of the dependency on additional
35 * frames being fed into the decoder to satisfy the b-frame dependencies.
37 * As such, the hardware can only be used effectively with a decode API that
38 * doesn't assume a 1:1 relationship between input packets and output frames.
39 * The new avcodec decode API is such an API (an m:n API) while the old one is
40 * 1:1. Consequently, we no longer support the old API, which allows us to avoid
41 * the vicious hacks that are required to approximate 1:1 operation.
44 /*****************************************************************************
46 ****************************************************************************/
48 #define _XOPEN_SOURCE 600
53 #include <libcrystalhd/bc_dts_types.h>
54 #include <libcrystalhd/bc_dts_defs.h>
55 #include <libcrystalhd/libcrystalhd_if.h>
60 #include "libavutil/imgutils.h"
61 #include "libavutil/intreadwrite.h"
62 #include "libavutil/opt.h"
68 /** Timeout parameter passed to DtsProcOutput() in us */
69 #define OUTPUT_PROC_TIMEOUT 50
70 /** Step between fake timestamps passed to hardware in units of 100ns */
71 #define TIMESTAMP_UNIT 100000
74 /*****************************************************************************
76 ****************************************************************************/
84 typedef struct OpaqueList {
85 struct OpaqueList *next;
86 uint64_t fake_timestamp;
87 uint64_t reordered_opaque;
92 AVCodecContext *avctx;
95 uint8_t *orig_extradata;
96 uint32_t orig_extradata_size;
101 uint8_t *sps_pps_buf;
102 uint32_t sps_pps_size;
104 uint8_t need_second_field;
115 static const AVOption options[] = {
116 { "crystalhd_downscale_width",
117 "Turn on downscaling to the specified width",
118 offsetof(CHDContext, sWidth),
119 AV_OPT_TYPE_INT, {.i64 = 0}, 0, UINT32_MAX,
120 AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM, },
125 /*****************************************************************************
127 ****************************************************************************/
129 static inline BC_MEDIA_SUBTYPE id2subtype(CHDContext *priv, enum AVCodecID id)
132 case AV_CODEC_ID_MPEG4:
133 return BC_MSUBTYPE_DIVX;
134 case AV_CODEC_ID_MSMPEG4V3:
135 return BC_MSUBTYPE_DIVX311;
136 case AV_CODEC_ID_MPEG2VIDEO:
137 return BC_MSUBTYPE_MPEG2VIDEO;
138 case AV_CODEC_ID_VC1:
139 return BC_MSUBTYPE_VC1;
140 case AV_CODEC_ID_WMV3:
141 return BC_MSUBTYPE_WMV3;
142 case AV_CODEC_ID_H264:
143 return priv->is_nal ? BC_MSUBTYPE_AVC1 : BC_MSUBTYPE_H264;
145 return BC_MSUBTYPE_INVALID;
149 static inline void print_frame_info(CHDContext *priv, BC_DTS_PROC_OUT *output)
151 av_log(priv->avctx, AV_LOG_TRACE, "\tYBuffSz: %u\n", output->YbuffSz);
152 av_log(priv->avctx, AV_LOG_TRACE, "\tYBuffDoneSz: %u\n",
153 output->YBuffDoneSz);
154 av_log(priv->avctx, AV_LOG_TRACE, "\tUVBuffDoneSz: %u\n",
155 output->UVBuffDoneSz);
156 av_log(priv->avctx, AV_LOG_TRACE, "\tTimestamp: %"PRIu64"\n",
157 output->PicInfo.timeStamp);
158 av_log(priv->avctx, AV_LOG_TRACE, "\tPicture Number: %u\n",
159 output->PicInfo.picture_number);
160 av_log(priv->avctx, AV_LOG_TRACE, "\tWidth: %u\n",
161 output->PicInfo.width);
162 av_log(priv->avctx, AV_LOG_TRACE, "\tHeight: %u\n",
163 output->PicInfo.height);
164 av_log(priv->avctx, AV_LOG_TRACE, "\tChroma: 0x%03x\n",
165 output->PicInfo.chroma_format);
166 av_log(priv->avctx, AV_LOG_TRACE, "\tPulldown: %u\n",
167 output->PicInfo.pulldown);
168 av_log(priv->avctx, AV_LOG_TRACE, "\tFlags: 0x%08x\n",
169 output->PicInfo.flags);
170 av_log(priv->avctx, AV_LOG_TRACE, "\tFrame Rate/Res: %u\n",
171 output->PicInfo.frame_rate);
172 av_log(priv->avctx, AV_LOG_TRACE, "\tAspect Ratio: %u\n",
173 output->PicInfo.aspect_ratio);
174 av_log(priv->avctx, AV_LOG_TRACE, "\tColor Primaries: %u\n",
175 output->PicInfo.colour_primaries);
176 av_log(priv->avctx, AV_LOG_TRACE, "\tMetaData: %u\n",
177 output->PicInfo.picture_meta_payload);
178 av_log(priv->avctx, AV_LOG_TRACE, "\tSession Number: %u\n",
179 output->PicInfo.sess_num);
180 av_log(priv->avctx, AV_LOG_TRACE, "\tycom: %u\n",
181 output->PicInfo.ycom);
182 av_log(priv->avctx, AV_LOG_TRACE, "\tCustom Aspect: %u\n",
183 output->PicInfo.custom_aspect_ratio_width_height);
184 av_log(priv->avctx, AV_LOG_TRACE, "\tFrames to Drop: %u\n",
185 output->PicInfo.n_drop);
186 av_log(priv->avctx, AV_LOG_TRACE, "\tH264 Valid Fields: 0x%08x\n",
187 output->PicInfo.other.h264.valid);
191 /*****************************************************************************
192 * OpaqueList functions
193 ****************************************************************************/
195 static uint64_t opaque_list_push(CHDContext *priv, uint64_t reordered_opaque)
197 OpaqueList *newNode = av_mallocz(sizeof (OpaqueList));
199 av_log(priv->avctx, AV_LOG_ERROR,
200 "Unable to allocate new node in OpaqueList.\n");
204 newNode->fake_timestamp = TIMESTAMP_UNIT;
205 priv->head = newNode;
207 newNode->fake_timestamp = priv->tail->fake_timestamp + TIMESTAMP_UNIT;
208 priv->tail->next = newNode;
210 priv->tail = newNode;
211 newNode->reordered_opaque = reordered_opaque;
213 return newNode->fake_timestamp;
217 * The OpaqueList is built in decode order, while elements will be removed
218 * in presentation order. If frames are reordered, this means we must be
219 * able to remove elements that are not the first element.
221 * Returned node must be freed by caller.
223 static OpaqueList *opaque_list_pop(CHDContext *priv, uint64_t fake_timestamp)
225 OpaqueList *node = priv->head;
228 av_log(priv->avctx, AV_LOG_ERROR,
229 "CrystalHD: Attempted to query non-existent timestamps.\n");
234 * The first element is special-cased because we have to manipulate
235 * the head pointer rather than the previous element in the list.
237 if (priv->head->fake_timestamp == fake_timestamp) {
238 priv->head = node->next;
240 if (!priv->head->next)
241 priv->tail = priv->head;
248 * The list is processed at arm's length so that we have the
249 * previous element available to rewrite its next pointer.
252 OpaqueList *current = node->next;
253 if (current->fake_timestamp == fake_timestamp) {
254 node->next = current->next;
259 current->next = NULL;
266 av_log(priv->avctx, AV_LOG_VERBOSE,
267 "CrystalHD: Couldn't match fake_timestamp.\n");
272 /*****************************************************************************
273 * Video decoder API function definitions
274 ****************************************************************************/
276 static void flush(AVCodecContext *avctx)
278 CHDContext *priv = avctx->priv_data;
280 priv->need_second_field = 0;
283 /* Flush mode 4 flushes all software and hardware buffers. */
284 DtsFlushInput(priv->dev, 4);
288 static av_cold int uninit(AVCodecContext *avctx)
290 CHDContext *priv = avctx->priv_data;
294 DtsStopDecoder(device);
295 DtsCloseDecoder(device);
296 DtsDeviceClose(device);
299 * Restore original extradata, so that if the decoder is
300 * reinitialised, the bitstream detection and filtering
301 * will work as expected.
303 if (priv->orig_extradata) {
304 av_free(avctx->extradata);
305 avctx->extradata = priv->orig_extradata;
306 avctx->extradata_size = priv->orig_extradata_size;
307 priv->orig_extradata = NULL;
308 priv->orig_extradata_size = 0;
312 av_bsf_free(&priv->bsfc);
315 av_freep(&priv->sps_pps_buf);
318 OpaqueList *node = priv->head;
320 OpaqueList *next = node->next;
330 static av_cold int init_bsf(AVCodecContext *avctx, const char *bsf_name)
332 CHDContext *priv = avctx->priv_data;
333 const AVBitStreamFilter *bsf;
335 void *extradata = NULL;
338 bsf = av_bsf_get_by_name(bsf_name);
340 av_log(avctx, AV_LOG_ERROR,
341 "Cannot open the %s BSF!\n", bsf_name);
342 return AVERROR_BSF_NOT_FOUND;
345 avret = av_bsf_alloc(bsf, &priv->bsfc);
350 avret = avcodec_parameters_from_context(priv->bsfc->par_in, avctx);
355 avret = av_bsf_init(priv->bsfc);
360 /* Back up the extradata so it can be restored at close time. */
361 priv->orig_extradata = avctx->extradata;
362 priv->orig_extradata_size = avctx->extradata_size;
364 size = priv->bsfc->par_out->extradata_size;
365 extradata = av_malloc(size + AV_INPUT_BUFFER_PADDING_SIZE);
367 av_log(avctx, AV_LOG_ERROR,
368 "Failed to allocate copy of extradata\n");
369 return AVERROR(ENOMEM);
371 memcpy(extradata, priv->bsfc->par_out->extradata, size);
373 avctx->extradata = extradata;
374 avctx->extradata_size = size;
379 static av_cold int init(AVCodecContext *avctx)
384 BC_INFO_CRYSTAL version;
385 BC_INPUT_FORMAT format = {
388 .OptFlags = 0x80000000 | vdecFrameRate59_94 | 0x40,
389 .width = avctx->width,
390 .height = avctx->height,
393 BC_MEDIA_SUBTYPE subtype;
395 uint32_t mode = DTS_PLAYBACK_MODE |
396 DTS_LOAD_FILE_PLAY_FW |
397 DTS_SKIP_TX_CHK_CPB |
398 DTS_PLAYBACK_DROP_RPT_MODE |
399 DTS_SINGLE_THREADED_MODE |
400 DTS_DFLT_RESOLUTION(vdecRESOLUTION_1080p23_976);
402 av_log(avctx, AV_LOG_VERBOSE, "CrystalHD Init for %s\n",
405 avctx->pix_fmt = AV_PIX_FMT_YUYV422;
407 /* Initialize the library */
408 priv = avctx->priv_data;
410 priv->is_nal = avctx->extradata_size > 0 && *(avctx->extradata) == 1;
413 subtype = id2subtype(priv, avctx->codec->id);
415 case BC_MSUBTYPE_AVC1:
416 avret = init_bsf(avctx, "h264_mp4toannexb");
420 subtype = BC_MSUBTYPE_H264;
421 format.startCodeSz = 4;
422 format.pMetaData = avctx->extradata;
423 format.metaDataSz = avctx->extradata_size;
425 case BC_MSUBTYPE_H264:
426 format.startCodeSz = 4;
428 case BC_MSUBTYPE_VC1:
429 case BC_MSUBTYPE_WVC1:
430 case BC_MSUBTYPE_WMV3:
431 case BC_MSUBTYPE_WMVA:
432 case BC_MSUBTYPE_MPEG2VIDEO:
433 case BC_MSUBTYPE_DIVX:
434 case BC_MSUBTYPE_DIVX311:
435 format.pMetaData = avctx->extradata;
436 format.metaDataSz = avctx->extradata_size;
439 av_log(avctx, AV_LOG_ERROR, "CrystalHD: Unknown codec name\n");
440 return AVERROR(EINVAL);
442 format.mSubtype = subtype;
445 format.bEnableScaling = 1;
446 format.ScalingParams.sWidth = priv->sWidth;
449 /* Get a decoder instance */
450 av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: starting up\n");
451 // Initialize the Link and Decoder devices
452 ret = DtsDeviceOpen(&priv->dev, mode);
453 if (ret != BC_STS_SUCCESS) {
454 av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: DtsDeviceOpen failed\n");
458 ret = DtsCrystalHDVersion(priv->dev, &version);
459 if (ret != BC_STS_SUCCESS) {
460 av_log(avctx, AV_LOG_VERBOSE,
461 "CrystalHD: DtsCrystalHDVersion failed\n");
464 priv->is_70012 = version.device == 0;
466 if (priv->is_70012 &&
467 (subtype == BC_MSUBTYPE_DIVX || subtype == BC_MSUBTYPE_DIVX311)) {
468 av_log(avctx, AV_LOG_VERBOSE,
469 "CrystalHD: BCM70012 doesn't support MPEG4-ASP/DivX/Xvid\n");
473 ret = DtsSetInputFormat(priv->dev, &format);
474 if (ret != BC_STS_SUCCESS) {
475 av_log(avctx, AV_LOG_ERROR, "CrystalHD: SetInputFormat failed\n");
479 ret = DtsOpenDecoder(priv->dev, BC_STREAM_TYPE_ES);
480 if (ret != BC_STS_SUCCESS) {
481 av_log(avctx, AV_LOG_ERROR, "CrystalHD: DtsOpenDecoder failed\n");
485 ret = DtsSetColorSpace(priv->dev, OUTPUT_MODE422_YUY2);
486 if (ret != BC_STS_SUCCESS) {
487 av_log(avctx, AV_LOG_ERROR, "CrystalHD: DtsSetColorSpace failed\n");
490 ret = DtsStartDecoder(priv->dev);
491 if (ret != BC_STS_SUCCESS) {
492 av_log(avctx, AV_LOG_ERROR, "CrystalHD: DtsStartDecoder failed\n");
495 ret = DtsStartCapture(priv->dev);
496 if (ret != BC_STS_SUCCESS) {
497 av_log(avctx, AV_LOG_ERROR, "CrystalHD: DtsStartCapture failed\n");
501 av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: Init complete.\n");
511 static inline CopyRet copy_frame(AVCodecContext *avctx,
512 BC_DTS_PROC_OUT *output,
513 AVFrame *frame, int *got_frame)
516 BC_DTS_STATUS decoder_status = { 0, };
519 CHDContext *priv = avctx->priv_data;
520 int64_t pkt_pts = AV_NOPTS_VALUE;
522 uint8_t bottom_field = (output->PicInfo.flags & VDEC_FLAG_BOTTOMFIELD) ==
523 VDEC_FLAG_BOTTOMFIELD;
524 uint8_t bottom_first = !!(output->PicInfo.flags & VDEC_FLAG_BOTTOM_FIRST);
526 int width = output->PicInfo.width;
527 int height = output->PicInfo.height;
529 uint8_t *src = output->Ybuff;
534 if (output->PicInfo.timeStamp != 0) {
535 OpaqueList *node = opaque_list_pop(priv, output->PicInfo.timeStamp);
537 pkt_pts = node->reordered_opaque;
541 * We will encounter a situation where a timestamp cannot be
542 * popped if a second field is being returned. In this case,
543 * each field has the same timestamp and the first one will
544 * cause it to be popped. We'll avoid overwriting the valid
548 av_log(avctx, AV_LOG_VERBOSE, "output \"pts\": %"PRIu64"\n",
549 output->PicInfo.timeStamp);
552 ret = DtsGetDriverStatus(priv->dev, &decoder_status);
553 if (ret != BC_STS_SUCCESS) {
554 av_log(avctx, AV_LOG_ERROR,
555 "CrystalHD: GetDriverStatus failed: %u\n", ret);
559 interlaced = output->PicInfo.flags & VDEC_FLAG_INTERLACED_SRC;
561 av_log(avctx, AV_LOG_VERBOSE, "Interlaced state: %d\n",
564 priv->need_second_field = interlaced && !priv->need_second_field;
566 if (!frame->data[0]) {
567 if (ff_get_buffer(avctx, frame, 0) < 0)
571 bwidth = av_image_get_linesize(avctx->pix_fmt, width, 0);
575 if (priv->is_70012) {
580 else if (width <= 1280)
583 sStride = av_image_get_linesize(avctx->pix_fmt, pStride, 0);
590 dStride = frame->linesize[0];
591 dst = frame->data[0];
593 av_log(priv->avctx, AV_LOG_VERBOSE, "CrystalHD: Copying out frame\n");
596 * The hardware doesn't return the first sample of a picture.
597 * Ignoring why it behaves this way, it's better to copy the sample from
598 * the second line, rather than the next sample across because the chroma
599 * values should be correct (assuming the decoded video was 4:2:0, which
602 *((uint32_t *)src) = *((uint32_t *)(src + sStride));
610 av_log(priv->avctx, AV_LOG_VERBOSE, "Interlaced: bottom field\n");
613 av_log(priv->avctx, AV_LOG_VERBOSE, "Interlaced: top field\n");
617 for (sY = 0; sY < height; dY++, sY++) {
618 memcpy(&(dst[dY * dStride]), &(src[sY * sStride]), bwidth);
622 av_image_copy_plane(dst, dStride, src, sStride, bwidth, height);
625 frame->interlaced_frame = interlaced;
627 frame->top_field_first = !bottom_first;
629 if (pkt_pts != AV_NOPTS_VALUE) {
630 frame->pts = pkt_pts;
632 FF_DISABLE_DEPRECATION_WARNINGS
633 frame->pkt_pts = pkt_pts;
634 FF_ENABLE_DEPRECATION_WARNINGS
638 frame->pkt_duration = 0;
639 frame->pkt_size = -1;
641 if (!priv->need_second_field) {
644 return RET_COPY_AGAIN;
651 static inline CopyRet receive_frame(AVCodecContext *avctx,
652 AVFrame *frame, int *got_frame)
655 BC_DTS_PROC_OUT output = {
656 .PicInfo.width = avctx->width,
657 .PicInfo.height = avctx->height,
659 CHDContext *priv = avctx->priv_data;
660 HANDLE dev = priv->dev;
664 // Request decoded data from the driver
665 ret = DtsProcOutputNoCopy(dev, OUTPUT_PROC_TIMEOUT, &output);
666 if (ret == BC_STS_FMT_CHANGE) {
667 av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: Initial format change\n");
668 avctx->width = output.PicInfo.width;
669 avctx->height = output.PicInfo.height;
670 switch ( output.PicInfo.aspect_ratio ) {
671 case vdecAspectRatioSquare:
672 avctx->sample_aspect_ratio = (AVRational) { 1, 1};
674 case vdecAspectRatio12_11:
675 avctx->sample_aspect_ratio = (AVRational) { 12, 11};
677 case vdecAspectRatio10_11:
678 avctx->sample_aspect_ratio = (AVRational) { 10, 11};
680 case vdecAspectRatio16_11:
681 avctx->sample_aspect_ratio = (AVRational) { 16, 11};
683 case vdecAspectRatio40_33:
684 avctx->sample_aspect_ratio = (AVRational) { 40, 33};
686 case vdecAspectRatio24_11:
687 avctx->sample_aspect_ratio = (AVRational) { 24, 11};
689 case vdecAspectRatio20_11:
690 avctx->sample_aspect_ratio = (AVRational) { 20, 11};
692 case vdecAspectRatio32_11:
693 avctx->sample_aspect_ratio = (AVRational) { 32, 11};
695 case vdecAspectRatio80_33:
696 avctx->sample_aspect_ratio = (AVRational) { 80, 33};
698 case vdecAspectRatio18_11:
699 avctx->sample_aspect_ratio = (AVRational) { 18, 11};
701 case vdecAspectRatio15_11:
702 avctx->sample_aspect_ratio = (AVRational) { 15, 11};
704 case vdecAspectRatio64_33:
705 avctx->sample_aspect_ratio = (AVRational) { 64, 33};
707 case vdecAspectRatio160_99:
708 avctx->sample_aspect_ratio = (AVRational) {160, 99};
710 case vdecAspectRatio4_3:
711 avctx->sample_aspect_ratio = (AVRational) { 4, 3};
713 case vdecAspectRatio16_9:
714 avctx->sample_aspect_ratio = (AVRational) { 16, 9};
716 case vdecAspectRatio221_1:
717 avctx->sample_aspect_ratio = (AVRational) {221, 1};
720 return RET_COPY_AGAIN;
721 } else if (ret == BC_STS_SUCCESS) {
723 if (output.PoutFlags & BC_POUT_FLAGS_PIB_VALID) {
724 if (avctx->codec->id == AV_CODEC_ID_MPEG4 &&
725 output.PicInfo.timeStamp == 0 && priv->bframe_bug) {
726 if (!priv->bframe_bug) {
727 av_log(avctx, AV_LOG_VERBOSE,
728 "CrystalHD: Not returning packed frame twice.\n");
730 DtsReleaseOutputBuffs(dev, NULL, FALSE);
731 return RET_COPY_AGAIN;
734 print_frame_info(priv, &output);
736 copy_ret = copy_frame(avctx, &output, frame, got_frame);
739 * An invalid frame has been consumed.
741 av_log(avctx, AV_LOG_ERROR, "CrystalHD: ProcOutput succeeded with "
743 copy_ret = RET_COPY_AGAIN;
745 DtsReleaseOutputBuffs(dev, NULL, FALSE);
748 } else if (ret == BC_STS_BUSY) {
749 return RET_COPY_AGAIN;
751 av_log(avctx, AV_LOG_ERROR, "CrystalHD: ProcOutput failed %d\n", ret);
756 static int crystalhd_decode_packet(AVCodecContext *avctx, const AVPacket *avpkt)
759 CHDContext *priv = avctx->priv_data;
760 HANDLE dev = priv->dev;
761 AVPacket filtered_packet = { 0 };
764 av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: decode_packet\n");
766 if (avpkt && avpkt->size) {
768 if (!priv->bframe_bug && (avpkt->size == 6 || avpkt->size == 7)) {
770 * Drop frames trigger the bug
772 av_log(avctx, AV_LOG_WARNING,
773 "CrystalHD: Enabling work-around for packed b-frame bug\n");
774 priv->bframe_bug = 1;
775 } else if (priv->bframe_bug && avpkt->size == 8) {
777 * Delay frames don't trigger the bug
779 av_log(avctx, AV_LOG_WARNING,
780 "CrystalHD: Disabling work-around for packed b-frame bug\n");
781 priv->bframe_bug = 0;
785 AVPacket filter_packet = { 0 };
787 ret = av_packet_ref(&filter_packet, avpkt);
789 av_log(avctx, AV_LOG_ERROR, "CrystalHD: mpv4toannexb filter "
790 "failed to ref input packet\n");
794 ret = av_bsf_send_packet(priv->bsfc, &filter_packet);
796 av_log(avctx, AV_LOG_ERROR, "CrystalHD: mpv4toannexb filter "
797 "failed to send input packet\n");
801 ret = av_bsf_receive_packet(priv->bsfc, &filtered_packet);
803 av_log(avctx, AV_LOG_ERROR, "CrystalHD: mpv4toannexb filter "
804 "failed to receive output packet\n");
808 avpkt = &filtered_packet;
809 av_packet_unref(&filter_packet);
813 * Despite being notionally opaque, either libcrystalhd or
814 * the hardware itself will mangle pts values that are too
815 * small or too large. The docs claim it should be in units
816 * of 100ns. Given that we're nominally dealing with a black
817 * box on both sides, any transform we do has no guarantee of
818 * avoiding mangling so we need to build a mapping to values
819 * we know will not be mangled.
821 pts = opaque_list_push(priv, avpkt->pts);
823 ret = AVERROR(ENOMEM);
826 av_log(priv->avctx, AV_LOG_VERBOSE,
827 "input \"pts\": %"PRIu64"\n", pts);
828 bc_ret = DtsProcInput(dev, avpkt->data, avpkt->size, pts, 0);
829 if (bc_ret == BC_STS_BUSY) {
830 av_log(avctx, AV_LOG_WARNING,
831 "CrystalHD: ProcInput returned busy\n");
832 ret = AVERROR(EAGAIN);
834 } else if (bc_ret != BC_STS_SUCCESS) {
835 av_log(avctx, AV_LOG_ERROR,
836 "CrystalHD: ProcInput failed: %u\n", ret);
841 av_log(avctx, AV_LOG_INFO, "CrystalHD: No more input data\n");
847 av_packet_unref(&filtered_packet);
851 static int crystalhd_receive_frame(AVCodecContext *avctx, AVFrame *frame)
854 BC_DTS_STATUS decoder_status = { 0, };
856 CHDContext *priv = avctx->priv_data;
857 HANDLE dev = priv->dev;
862 av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: receive_frame\n");
864 ret = ff_decode_get_packet(avctx, &pkt);
865 if (ret < 0 && ret != AVERROR_EOF) {
869 while (pkt.size > DtsTxFreeSize(dev)) {
871 * Block until there is space in the buffer for the next packet.
872 * We assume that the hardware will make forward progress at this
873 * point, although in pathological cases that may not happen.
875 av_log(avctx, AV_LOG_TRACE, "CrystalHD: Waiting for space in input buffer\n");
878 ret = crystalhd_decode_packet(avctx, &pkt);
879 av_packet_unref(&pkt);
880 // crystalhd_is_buffer_full() should avoid this.
881 if (ret == AVERROR(EAGAIN)) {
882 ret = AVERROR_EXTERNAL;
884 if (ret < 0 && ret != AVERROR_EOF) {
889 bc_ret = DtsGetDriverStatus(dev, &decoder_status);
890 if (bc_ret != BC_STS_SUCCESS) {
891 av_log(avctx, AV_LOG_ERROR, "CrystalHD: GetDriverStatus failed\n");
895 if (decoder_status.ReadyListCount == 0) {
896 av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: Insufficient frames ready. Returning\n");
902 rec_ret = receive_frame(avctx, frame, &got_frame);
903 } while (rec_ret == RET_COPY_AGAIN);
905 if (rec_ret == RET_ERROR) {
907 } else if (got_frame == 0) {
908 return priv->draining ? AVERROR_EOF : AVERROR(EAGAIN);
914 #define DEFINE_CRYSTALHD_DECODER(x, X) \
915 static const AVClass x##_crystalhd_class = { \
916 .class_name = #x "_crystalhd", \
917 .item_name = av_default_item_name, \
919 .version = LIBAVUTIL_VERSION_INT, \
921 AVCodec ff_##x##_crystalhd_decoder = { \
922 .name = #x "_crystalhd", \
923 .long_name = NULL_IF_CONFIG_SMALL("CrystalHD " #X " decoder"), \
924 .type = AVMEDIA_TYPE_VIDEO, \
925 .id = AV_CODEC_ID_##X, \
926 .priv_data_size = sizeof(CHDContext), \
927 .priv_class = &x##_crystalhd_class, \
930 .receive_frame = crystalhd_receive_frame, \
932 .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING, \
933 .pix_fmts = (const enum AVPixelFormat[]){AV_PIX_FMT_YUYV422, AV_PIX_FMT_NONE}, \
936 #if CONFIG_H264_CRYSTALHD_DECODER
937 DEFINE_CRYSTALHD_DECODER(h264, H264)
940 #if CONFIG_MPEG2_CRYSTALHD_DECODER
941 DEFINE_CRYSTALHD_DECODER(mpeg2, MPEG2VIDEO)
944 #if CONFIG_MPEG4_CRYSTALHD_DECODER
945 DEFINE_CRYSTALHD_DECODER(mpeg4, MPEG4)
948 #if CONFIG_MSMPEG4_CRYSTALHD_DECODER
949 DEFINE_CRYSTALHD_DECODER(msmpeg4, MSMPEG4V3)
952 #if CONFIG_VC1_CRYSTALHD_DECODER
953 DEFINE_CRYSTALHD_DECODER(vc1, VC1)
956 #if CONFIG_WMV3_CRYSTALHD_DECODER
957 DEFINE_CRYSTALHD_DECODER(wmv3, WMV3)