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;
96 uint8_t need_second_field;
107 static const AVOption options[] = {
108 { "crystalhd_downscale_width",
109 "Turn on downscaling to the specified width",
110 offsetof(CHDContext, sWidth),
111 AV_OPT_TYPE_INT, {.i64 = 0}, 0, UINT32_MAX,
112 AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM, },
117 /*****************************************************************************
119 ****************************************************************************/
121 static inline BC_MEDIA_SUBTYPE id2subtype(CHDContext *priv, enum AVCodecID id)
124 case AV_CODEC_ID_MPEG4:
125 return BC_MSUBTYPE_DIVX;
126 case AV_CODEC_ID_MSMPEG4V3:
127 return BC_MSUBTYPE_DIVX311;
128 case AV_CODEC_ID_MPEG2VIDEO:
129 return BC_MSUBTYPE_MPEG2VIDEO;
130 case AV_CODEC_ID_VC1:
131 return BC_MSUBTYPE_VC1;
132 case AV_CODEC_ID_WMV3:
133 return BC_MSUBTYPE_WMV3;
134 case AV_CODEC_ID_H264:
135 return BC_MSUBTYPE_H264;
137 return BC_MSUBTYPE_INVALID;
141 static inline void print_frame_info(CHDContext *priv, BC_DTS_PROC_OUT *output)
143 av_log(priv->avctx, AV_LOG_TRACE, "\tYBuffSz: %u\n", output->YbuffSz);
144 av_log(priv->avctx, AV_LOG_TRACE, "\tYBuffDoneSz: %u\n",
145 output->YBuffDoneSz);
146 av_log(priv->avctx, AV_LOG_TRACE, "\tUVBuffDoneSz: %u\n",
147 output->UVBuffDoneSz);
148 av_log(priv->avctx, AV_LOG_TRACE, "\tTimestamp: %"PRIu64"\n",
149 output->PicInfo.timeStamp);
150 av_log(priv->avctx, AV_LOG_TRACE, "\tPicture Number: %u\n",
151 output->PicInfo.picture_number);
152 av_log(priv->avctx, AV_LOG_TRACE, "\tWidth: %u\n",
153 output->PicInfo.width);
154 av_log(priv->avctx, AV_LOG_TRACE, "\tHeight: %u\n",
155 output->PicInfo.height);
156 av_log(priv->avctx, AV_LOG_TRACE, "\tChroma: 0x%03x\n",
157 output->PicInfo.chroma_format);
158 av_log(priv->avctx, AV_LOG_TRACE, "\tPulldown: %u\n",
159 output->PicInfo.pulldown);
160 av_log(priv->avctx, AV_LOG_TRACE, "\tFlags: 0x%08x\n",
161 output->PicInfo.flags);
162 av_log(priv->avctx, AV_LOG_TRACE, "\tFrame Rate/Res: %u\n",
163 output->PicInfo.frame_rate);
164 av_log(priv->avctx, AV_LOG_TRACE, "\tAspect Ratio: %u\n",
165 output->PicInfo.aspect_ratio);
166 av_log(priv->avctx, AV_LOG_TRACE, "\tColor Primaries: %u\n",
167 output->PicInfo.colour_primaries);
168 av_log(priv->avctx, AV_LOG_TRACE, "\tMetaData: %u\n",
169 output->PicInfo.picture_meta_payload);
170 av_log(priv->avctx, AV_LOG_TRACE, "\tSession Number: %u\n",
171 output->PicInfo.sess_num);
172 av_log(priv->avctx, AV_LOG_TRACE, "\tycom: %u\n",
173 output->PicInfo.ycom);
174 av_log(priv->avctx, AV_LOG_TRACE, "\tCustom Aspect: %u\n",
175 output->PicInfo.custom_aspect_ratio_width_height);
176 av_log(priv->avctx, AV_LOG_TRACE, "\tFrames to Drop: %u\n",
177 output->PicInfo.n_drop);
178 av_log(priv->avctx, AV_LOG_TRACE, "\tH264 Valid Fields: 0x%08x\n",
179 output->PicInfo.other.h264.valid);
183 /*****************************************************************************
184 * OpaqueList functions
185 ****************************************************************************/
187 static uint64_t opaque_list_push(CHDContext *priv, uint64_t reordered_opaque)
189 OpaqueList *newNode = av_mallocz(sizeof (OpaqueList));
191 av_log(priv->avctx, AV_LOG_ERROR,
192 "Unable to allocate new node in OpaqueList.\n");
196 newNode->fake_timestamp = TIMESTAMP_UNIT;
197 priv->head = newNode;
199 newNode->fake_timestamp = priv->tail->fake_timestamp + TIMESTAMP_UNIT;
200 priv->tail->next = newNode;
202 priv->tail = newNode;
203 newNode->reordered_opaque = reordered_opaque;
205 return newNode->fake_timestamp;
209 * The OpaqueList is built in decode order, while elements will be removed
210 * in presentation order. If frames are reordered, this means we must be
211 * able to remove elements that are not the first element.
213 * Returned node must be freed by caller.
215 static OpaqueList *opaque_list_pop(CHDContext *priv, uint64_t fake_timestamp)
217 OpaqueList *node = priv->head;
220 av_log(priv->avctx, AV_LOG_ERROR,
221 "CrystalHD: Attempted to query non-existent timestamps.\n");
226 * The first element is special-cased because we have to manipulate
227 * the head pointer rather than the previous element in the list.
229 if (priv->head->fake_timestamp == fake_timestamp) {
230 priv->head = node->next;
232 if (!priv->head->next)
233 priv->tail = priv->head;
240 * The list is processed at arm's length so that we have the
241 * previous element available to rewrite its next pointer.
244 OpaqueList *current = node->next;
245 if (current->fake_timestamp == fake_timestamp) {
246 node->next = current->next;
251 current->next = NULL;
258 av_log(priv->avctx, AV_LOG_VERBOSE,
259 "CrystalHD: Couldn't match fake_timestamp.\n");
264 /*****************************************************************************
265 * Video decoder API function definitions
266 ****************************************************************************/
268 static void flush(AVCodecContext *avctx)
270 CHDContext *priv = avctx->priv_data;
272 priv->need_second_field = 0;
275 /* Flush mode 4 flushes all software and hardware buffers. */
276 DtsFlushInput(priv->dev, 4);
280 static av_cold int uninit(AVCodecContext *avctx)
282 CHDContext *priv = avctx->priv_data;
286 DtsStopDecoder(device);
287 DtsCloseDecoder(device);
288 DtsDeviceClose(device);
291 OpaqueList *node = priv->head;
293 OpaqueList *next = node->next;
302 static av_cold int init(AVCodecContext *avctx)
306 BC_INFO_CRYSTAL version;
307 BC_INPUT_FORMAT format = {
310 .OptFlags = 0x80000000 | vdecFrameRate59_94 | 0x40,
311 .width = avctx->width,
312 .height = avctx->height,
315 BC_MEDIA_SUBTYPE subtype;
317 uint32_t mode = DTS_PLAYBACK_MODE |
318 DTS_LOAD_FILE_PLAY_FW |
319 DTS_SKIP_TX_CHK_CPB |
320 DTS_PLAYBACK_DROP_RPT_MODE |
321 DTS_SINGLE_THREADED_MODE |
322 DTS_DFLT_RESOLUTION(vdecRESOLUTION_1080p23_976);
324 av_log(avctx, AV_LOG_VERBOSE, "CrystalHD Init for %s\n",
327 avctx->pix_fmt = AV_PIX_FMT_YUYV422;
329 /* Initialize the library */
330 priv = avctx->priv_data;
334 subtype = id2subtype(priv, avctx->codec->id);
336 case BC_MSUBTYPE_H264:
337 format.startCodeSz = 4;
339 case BC_MSUBTYPE_VC1:
340 case BC_MSUBTYPE_WVC1:
341 case BC_MSUBTYPE_WMV3:
342 case BC_MSUBTYPE_WMVA:
343 case BC_MSUBTYPE_MPEG2VIDEO:
344 case BC_MSUBTYPE_DIVX:
345 case BC_MSUBTYPE_DIVX311:
346 format.pMetaData = avctx->extradata;
347 format.metaDataSz = avctx->extradata_size;
350 av_log(avctx, AV_LOG_ERROR, "CrystalHD: Unknown codec name\n");
351 return AVERROR(EINVAL);
353 format.mSubtype = subtype;
356 format.bEnableScaling = 1;
357 format.ScalingParams.sWidth = priv->sWidth;
360 /* Get a decoder instance */
361 av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: starting up\n");
362 // Initialize the Link and Decoder devices
363 ret = DtsDeviceOpen(&priv->dev, mode);
364 if (ret != BC_STS_SUCCESS) {
365 av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: DtsDeviceOpen failed\n");
369 ret = DtsCrystalHDVersion(priv->dev, &version);
370 if (ret != BC_STS_SUCCESS) {
371 av_log(avctx, AV_LOG_VERBOSE,
372 "CrystalHD: DtsCrystalHDVersion failed\n");
375 priv->is_70012 = version.device == 0;
377 if (priv->is_70012 &&
378 (subtype == BC_MSUBTYPE_DIVX || subtype == BC_MSUBTYPE_DIVX311)) {
379 av_log(avctx, AV_LOG_VERBOSE,
380 "CrystalHD: BCM70012 doesn't support MPEG4-ASP/DivX/Xvid\n");
384 ret = DtsSetInputFormat(priv->dev, &format);
385 if (ret != BC_STS_SUCCESS) {
386 av_log(avctx, AV_LOG_ERROR, "CrystalHD: SetInputFormat failed\n");
390 ret = DtsOpenDecoder(priv->dev, BC_STREAM_TYPE_ES);
391 if (ret != BC_STS_SUCCESS) {
392 av_log(avctx, AV_LOG_ERROR, "CrystalHD: DtsOpenDecoder failed\n");
396 ret = DtsSetColorSpace(priv->dev, OUTPUT_MODE422_YUY2);
397 if (ret != BC_STS_SUCCESS) {
398 av_log(avctx, AV_LOG_ERROR, "CrystalHD: DtsSetColorSpace failed\n");
401 ret = DtsStartDecoder(priv->dev);
402 if (ret != BC_STS_SUCCESS) {
403 av_log(avctx, AV_LOG_ERROR, "CrystalHD: DtsStartDecoder failed\n");
406 ret = DtsStartCapture(priv->dev);
407 if (ret != BC_STS_SUCCESS) {
408 av_log(avctx, AV_LOG_ERROR, "CrystalHD: DtsStartCapture failed\n");
412 av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: Init complete.\n");
422 static inline CopyRet copy_frame(AVCodecContext *avctx,
423 BC_DTS_PROC_OUT *output,
424 AVFrame *frame, int *got_frame)
427 BC_DTS_STATUS decoder_status = { 0, };
430 CHDContext *priv = avctx->priv_data;
431 int64_t pkt_pts = AV_NOPTS_VALUE;
433 uint8_t bottom_field = (output->PicInfo.flags & VDEC_FLAG_BOTTOMFIELD) ==
434 VDEC_FLAG_BOTTOMFIELD;
435 uint8_t bottom_first = !!(output->PicInfo.flags & VDEC_FLAG_BOTTOM_FIRST);
437 int width = output->PicInfo.width;
438 int height = output->PicInfo.height;
440 uint8_t *src = output->Ybuff;
445 if (output->PicInfo.timeStamp != 0) {
446 OpaqueList *node = opaque_list_pop(priv, output->PicInfo.timeStamp);
448 pkt_pts = node->reordered_opaque;
452 * We will encounter a situation where a timestamp cannot be
453 * popped if a second field is being returned. In this case,
454 * each field has the same timestamp and the first one will
455 * cause it to be popped. We'll avoid overwriting the valid
459 av_log(avctx, AV_LOG_VERBOSE, "output \"pts\": %"PRIu64"\n",
460 output->PicInfo.timeStamp);
463 ret = DtsGetDriverStatus(priv->dev, &decoder_status);
464 if (ret != BC_STS_SUCCESS) {
465 av_log(avctx, AV_LOG_ERROR,
466 "CrystalHD: GetDriverStatus failed: %u\n", ret);
470 interlaced = output->PicInfo.flags & VDEC_FLAG_INTERLACED_SRC;
472 av_log(avctx, AV_LOG_VERBOSE, "Interlaced state: %d\n",
475 priv->need_second_field = interlaced && !priv->need_second_field;
477 if (!frame->data[0]) {
478 if (ff_get_buffer(avctx, frame, 0) < 0)
482 bwidth = av_image_get_linesize(avctx->pix_fmt, width, 0);
486 if (priv->is_70012) {
491 else if (width <= 1280)
494 sStride = av_image_get_linesize(avctx->pix_fmt, pStride, 0);
501 dStride = frame->linesize[0];
502 dst = frame->data[0];
504 av_log(priv->avctx, AV_LOG_VERBOSE, "CrystalHD: Copying out frame\n");
507 * The hardware doesn't return the first sample of a picture.
508 * Ignoring why it behaves this way, it's better to copy the sample from
509 * the second line, rather than the next sample across because the chroma
510 * values should be correct (assuming the decoded video was 4:2:0, which
513 *((uint32_t *)src) = *((uint32_t *)(src + sStride));
521 av_log(priv->avctx, AV_LOG_VERBOSE, "Interlaced: bottom field\n");
524 av_log(priv->avctx, AV_LOG_VERBOSE, "Interlaced: top field\n");
528 for (sY = 0; sY < height; dY++, sY++) {
529 memcpy(&(dst[dY * dStride]), &(src[sY * sStride]), bwidth);
533 av_image_copy_plane(dst, dStride, src, sStride, bwidth, height);
536 frame->interlaced_frame = interlaced;
538 frame->top_field_first = !bottom_first;
540 if (pkt_pts != AV_NOPTS_VALUE) {
541 frame->pts = pkt_pts;
543 FF_DISABLE_DEPRECATION_WARNINGS
544 frame->pkt_pts = pkt_pts;
545 FF_ENABLE_DEPRECATION_WARNINGS
549 frame->pkt_duration = 0;
550 frame->pkt_size = -1;
552 if (!priv->need_second_field) {
555 return RET_COPY_AGAIN;
562 static inline CopyRet receive_frame(AVCodecContext *avctx,
563 AVFrame *frame, int *got_frame)
566 BC_DTS_PROC_OUT output = {
567 .PicInfo.width = avctx->width,
568 .PicInfo.height = avctx->height,
570 CHDContext *priv = avctx->priv_data;
571 HANDLE dev = priv->dev;
575 // Request decoded data from the driver
576 ret = DtsProcOutputNoCopy(dev, OUTPUT_PROC_TIMEOUT, &output);
577 if (ret == BC_STS_FMT_CHANGE) {
578 av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: Initial format change\n");
579 avctx->width = output.PicInfo.width;
580 avctx->height = output.PicInfo.height;
581 switch ( output.PicInfo.aspect_ratio ) {
582 case vdecAspectRatioSquare:
583 avctx->sample_aspect_ratio = (AVRational) { 1, 1};
585 case vdecAspectRatio12_11:
586 avctx->sample_aspect_ratio = (AVRational) { 12, 11};
588 case vdecAspectRatio10_11:
589 avctx->sample_aspect_ratio = (AVRational) { 10, 11};
591 case vdecAspectRatio16_11:
592 avctx->sample_aspect_ratio = (AVRational) { 16, 11};
594 case vdecAspectRatio40_33:
595 avctx->sample_aspect_ratio = (AVRational) { 40, 33};
597 case vdecAspectRatio24_11:
598 avctx->sample_aspect_ratio = (AVRational) { 24, 11};
600 case vdecAspectRatio20_11:
601 avctx->sample_aspect_ratio = (AVRational) { 20, 11};
603 case vdecAspectRatio32_11:
604 avctx->sample_aspect_ratio = (AVRational) { 32, 11};
606 case vdecAspectRatio80_33:
607 avctx->sample_aspect_ratio = (AVRational) { 80, 33};
609 case vdecAspectRatio18_11:
610 avctx->sample_aspect_ratio = (AVRational) { 18, 11};
612 case vdecAspectRatio15_11:
613 avctx->sample_aspect_ratio = (AVRational) { 15, 11};
615 case vdecAspectRatio64_33:
616 avctx->sample_aspect_ratio = (AVRational) { 64, 33};
618 case vdecAspectRatio160_99:
619 avctx->sample_aspect_ratio = (AVRational) {160, 99};
621 case vdecAspectRatio4_3:
622 avctx->sample_aspect_ratio = (AVRational) { 4, 3};
624 case vdecAspectRatio16_9:
625 avctx->sample_aspect_ratio = (AVRational) { 16, 9};
627 case vdecAspectRatio221_1:
628 avctx->sample_aspect_ratio = (AVRational) {221, 1};
631 return RET_COPY_AGAIN;
632 } else if (ret == BC_STS_SUCCESS) {
634 if (output.PoutFlags & BC_POUT_FLAGS_PIB_VALID) {
635 if (avctx->codec->id == AV_CODEC_ID_MPEG4 &&
636 output.PicInfo.timeStamp == 0 && priv->bframe_bug) {
637 if (!priv->bframe_bug) {
638 av_log(avctx, AV_LOG_VERBOSE,
639 "CrystalHD: Not returning packed frame twice.\n");
641 DtsReleaseOutputBuffs(dev, NULL, FALSE);
642 return RET_COPY_AGAIN;
645 print_frame_info(priv, &output);
647 copy_ret = copy_frame(avctx, &output, frame, got_frame);
650 * An invalid frame has been consumed.
652 av_log(avctx, AV_LOG_ERROR, "CrystalHD: ProcOutput succeeded with "
654 copy_ret = RET_COPY_AGAIN;
656 DtsReleaseOutputBuffs(dev, NULL, FALSE);
659 } else if (ret == BC_STS_BUSY) {
660 return RET_COPY_AGAIN;
662 av_log(avctx, AV_LOG_ERROR, "CrystalHD: ProcOutput failed %d\n", ret);
667 static int crystalhd_decode_packet(AVCodecContext *avctx, const AVPacket *avpkt)
670 CHDContext *priv = avctx->priv_data;
671 HANDLE dev = priv->dev;
672 AVPacket filtered_packet = { 0 };
675 av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: decode_packet\n");
677 if (avpkt && avpkt->size) {
679 if (!priv->bframe_bug && (avpkt->size == 6 || avpkt->size == 7)) {
681 * Drop frames trigger the bug
683 av_log(avctx, AV_LOG_WARNING,
684 "CrystalHD: Enabling work-around for packed b-frame bug\n");
685 priv->bframe_bug = 1;
686 } else if (priv->bframe_bug && avpkt->size == 8) {
688 * Delay frames don't trigger the bug
690 av_log(avctx, AV_LOG_WARNING,
691 "CrystalHD: Disabling work-around for packed b-frame bug\n");
692 priv->bframe_bug = 0;
696 * Despite being notionally opaque, either libcrystalhd or
697 * the hardware itself will mangle pts values that are too
698 * small or too large. The docs claim it should be in units
699 * of 100ns. Given that we're nominally dealing with a black
700 * box on both sides, any transform we do has no guarantee of
701 * avoiding mangling so we need to build a mapping to values
702 * we know will not be mangled.
704 pts = opaque_list_push(priv, avpkt->pts);
706 ret = AVERROR(ENOMEM);
709 av_log(priv->avctx, AV_LOG_VERBOSE,
710 "input \"pts\": %"PRIu64"\n", pts);
711 bc_ret = DtsProcInput(dev, avpkt->data, avpkt->size, pts, 0);
712 if (bc_ret == BC_STS_BUSY) {
713 av_log(avctx, AV_LOG_WARNING,
714 "CrystalHD: ProcInput returned busy\n");
715 ret = AVERROR(EAGAIN);
717 } else if (bc_ret != BC_STS_SUCCESS) {
718 av_log(avctx, AV_LOG_ERROR,
719 "CrystalHD: ProcInput failed: %u\n", ret);
724 av_log(avctx, AV_LOG_INFO, "CrystalHD: No more input data\n");
730 av_packet_unref(&filtered_packet);
734 static int crystalhd_receive_frame(AVCodecContext *avctx, AVFrame *frame)
737 BC_DTS_STATUS decoder_status = { 0, };
739 CHDContext *priv = avctx->priv_data;
740 HANDLE dev = priv->dev;
745 av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: receive_frame\n");
747 ret = ff_decode_get_packet(avctx, &pkt);
748 if (ret < 0 && ret != AVERROR_EOF) {
752 while (pkt.size > DtsTxFreeSize(dev)) {
754 * Block until there is space in the buffer for the next packet.
755 * We assume that the hardware will make forward progress at this
756 * point, although in pathological cases that may not happen.
758 av_log(avctx, AV_LOG_TRACE, "CrystalHD: Waiting for space in input buffer\n");
761 ret = crystalhd_decode_packet(avctx, &pkt);
762 av_packet_unref(&pkt);
763 // crystalhd_is_buffer_full() should avoid this.
764 if (ret == AVERROR(EAGAIN)) {
765 ret = AVERROR_EXTERNAL;
767 if (ret < 0 && ret != AVERROR_EOF) {
772 bc_ret = DtsGetDriverStatus(dev, &decoder_status);
773 if (bc_ret != BC_STS_SUCCESS) {
774 av_log(avctx, AV_LOG_ERROR, "CrystalHD: GetDriverStatus failed\n");
778 if (decoder_status.ReadyListCount == 0) {
779 av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: Insufficient frames ready. Returning\n");
785 rec_ret = receive_frame(avctx, frame, &got_frame);
786 } while (rec_ret == RET_COPY_AGAIN);
788 if (rec_ret == RET_ERROR) {
790 } else if (got_frame == 0) {
791 return priv->draining ? AVERROR_EOF : AVERROR(EAGAIN);
797 #define DEFINE_CRYSTALHD_DECODER(x, X, bsf_name) \
798 static const AVClass x##_crystalhd_class = { \
799 .class_name = #x "_crystalhd", \
800 .item_name = av_default_item_name, \
802 .version = LIBAVUTIL_VERSION_INT, \
804 AVCodec ff_##x##_crystalhd_decoder = { \
805 .name = #x "_crystalhd", \
806 .long_name = NULL_IF_CONFIG_SMALL("CrystalHD " #X " decoder"), \
807 .type = AVMEDIA_TYPE_VIDEO, \
808 .id = AV_CODEC_ID_##X, \
809 .priv_data_size = sizeof(CHDContext), \
810 .priv_class = &x##_crystalhd_class, \
813 .receive_frame = crystalhd_receive_frame, \
816 .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING, \
817 .pix_fmts = (const enum AVPixelFormat[]){AV_PIX_FMT_YUYV422, AV_PIX_FMT_NONE}, \
820 #if CONFIG_H264_CRYSTALHD_DECODER
821 DEFINE_CRYSTALHD_DECODER(h264, H264, "h264_mp4toannexb")
824 #if CONFIG_MPEG2_CRYSTALHD_DECODER
825 DEFINE_CRYSTALHD_DECODER(mpeg2, MPEG2VIDEO, NULL)
828 #if CONFIG_MPEG4_CRYSTALHD_DECODER
829 DEFINE_CRYSTALHD_DECODER(mpeg4, MPEG4, NULL)
832 #if CONFIG_MSMPEG4_CRYSTALHD_DECODER
833 DEFINE_CRYSTALHD_DECODER(msmpeg4, MSMPEG4V3, NULL)
836 #if CONFIG_VC1_CRYSTALHD_DECODER
837 DEFINE_CRYSTALHD_DECODER(vc1, VC1, NULL)
840 #if CONFIG_WMV3_CRYSTALHD_DECODER
841 DEFINE_CRYSTALHD_DECODER(wmv3, WMV3, NULL)