00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 #define _XOPEN_SOURCE 600
00077 #include <inttypes.h>
00078 #include <stdio.h>
00079 #include <stdlib.h>
00080 #include <unistd.h>
00081
00082 #include <libcrystalhd/bc_dts_types.h>
00083 #include <libcrystalhd/bc_dts_defs.h>
00084 #include <libcrystalhd/libcrystalhd_if.h>
00085
00086 #include "avcodec.h"
00087 #include "h264.h"
00088 #include "internal.h"
00089 #include "libavutil/imgutils.h"
00090 #include "libavutil/intreadwrite.h"
00091 #include "libavutil/opt.h"
00092
00094 #define OUTPUT_PROC_TIMEOUT 50
00095
00096 #define TIMESTAMP_UNIT 100000
00097
00098 #define BASE_WAIT 10000
00099
00100 #define WAIT_UNIT 1000
00101
00102
00103
00104
00105
00106
00107 typedef enum {
00108 RET_ERROR = -1,
00109 RET_OK = 0,
00110 RET_COPY_AGAIN = 1,
00111 RET_SKIP_NEXT_COPY = 2,
00112 RET_COPY_NEXT_FIELD = 3,
00113 } CopyRet;
00114
00115 typedef struct OpaqueList {
00116 struct OpaqueList *next;
00117 uint64_t fake_timestamp;
00118 uint64_t reordered_opaque;
00119 uint8_t pic_type;
00120 } OpaqueList;
00121
00122 typedef struct {
00123 AVClass *av_class;
00124 AVCodecContext *avctx;
00125 AVFrame pic;
00126 HANDLE dev;
00127
00128 uint8_t *orig_extradata;
00129 uint32_t orig_extradata_size;
00130
00131 AVBitStreamFilterContext *bsfc;
00132 AVCodecParserContext *parser;
00133
00134 uint8_t is_70012;
00135 uint8_t *sps_pps_buf;
00136 uint32_t sps_pps_size;
00137 uint8_t is_nal;
00138 uint8_t output_ready;
00139 uint8_t need_second_field;
00140 uint8_t skip_next_output;
00141 uint64_t decode_wait;
00142
00143 uint64_t last_picture;
00144
00145 OpaqueList *head;
00146 OpaqueList *tail;
00147
00148
00149 uint32_t sWidth;
00150 uint8_t bframe_bug;
00151 } CHDContext;
00152
00153 static const AVOption options[] = {
00154 { "crystalhd_downscale_width",
00155 "Turn on downscaling to the specified width",
00156 offsetof(CHDContext, sWidth),
00157 AV_OPT_TYPE_INT, {.i64 = 0}, 0, UINT32_MAX,
00158 AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM, },
00159 { NULL, },
00160 };
00161
00162
00163
00164
00165
00166
00167 static inline BC_MEDIA_SUBTYPE id2subtype(CHDContext *priv, enum AVCodecID id)
00168 {
00169 switch (id) {
00170 case AV_CODEC_ID_MPEG4:
00171 return BC_MSUBTYPE_DIVX;
00172 case AV_CODEC_ID_MSMPEG4V3:
00173 return BC_MSUBTYPE_DIVX311;
00174 case AV_CODEC_ID_MPEG2VIDEO:
00175 return BC_MSUBTYPE_MPEG2VIDEO;
00176 case AV_CODEC_ID_VC1:
00177 return BC_MSUBTYPE_VC1;
00178 case AV_CODEC_ID_WMV3:
00179 return BC_MSUBTYPE_WMV3;
00180 case AV_CODEC_ID_H264:
00181 return priv->is_nal ? BC_MSUBTYPE_AVC1 : BC_MSUBTYPE_H264;
00182 default:
00183 return BC_MSUBTYPE_INVALID;
00184 }
00185 }
00186
00187 static inline void print_frame_info(CHDContext *priv, BC_DTS_PROC_OUT *output)
00188 {
00189 av_log(priv->avctx, AV_LOG_VERBOSE, "\tYBuffSz: %u\n", output->YbuffSz);
00190 av_log(priv->avctx, AV_LOG_VERBOSE, "\tYBuffDoneSz: %u\n",
00191 output->YBuffDoneSz);
00192 av_log(priv->avctx, AV_LOG_VERBOSE, "\tUVBuffDoneSz: %u\n",
00193 output->UVBuffDoneSz);
00194 av_log(priv->avctx, AV_LOG_VERBOSE, "\tTimestamp: %"PRIu64"\n",
00195 output->PicInfo.timeStamp);
00196 av_log(priv->avctx, AV_LOG_VERBOSE, "\tPicture Number: %u\n",
00197 output->PicInfo.picture_number);
00198 av_log(priv->avctx, AV_LOG_VERBOSE, "\tWidth: %u\n",
00199 output->PicInfo.width);
00200 av_log(priv->avctx, AV_LOG_VERBOSE, "\tHeight: %u\n",
00201 output->PicInfo.height);
00202 av_log(priv->avctx, AV_LOG_VERBOSE, "\tChroma: 0x%03x\n",
00203 output->PicInfo.chroma_format);
00204 av_log(priv->avctx, AV_LOG_VERBOSE, "\tPulldown: %u\n",
00205 output->PicInfo.pulldown);
00206 av_log(priv->avctx, AV_LOG_VERBOSE, "\tFlags: 0x%08x\n",
00207 output->PicInfo.flags);
00208 av_log(priv->avctx, AV_LOG_VERBOSE, "\tFrame Rate/Res: %u\n",
00209 output->PicInfo.frame_rate);
00210 av_log(priv->avctx, AV_LOG_VERBOSE, "\tAspect Ratio: %u\n",
00211 output->PicInfo.aspect_ratio);
00212 av_log(priv->avctx, AV_LOG_VERBOSE, "\tColor Primaries: %u\n",
00213 output->PicInfo.colour_primaries);
00214 av_log(priv->avctx, AV_LOG_VERBOSE, "\tMetaData: %u\n",
00215 output->PicInfo.picture_meta_payload);
00216 av_log(priv->avctx, AV_LOG_VERBOSE, "\tSession Number: %u\n",
00217 output->PicInfo.sess_num);
00218 av_log(priv->avctx, AV_LOG_VERBOSE, "\tycom: %u\n",
00219 output->PicInfo.ycom);
00220 av_log(priv->avctx, AV_LOG_VERBOSE, "\tCustom Aspect: %u\n",
00221 output->PicInfo.custom_aspect_ratio_width_height);
00222 av_log(priv->avctx, AV_LOG_VERBOSE, "\tFrames to Drop: %u\n",
00223 output->PicInfo.n_drop);
00224 av_log(priv->avctx, AV_LOG_VERBOSE, "\tH264 Valid Fields: 0x%08x\n",
00225 output->PicInfo.other.h264.valid);
00226 }
00227
00228
00229
00230
00231
00232
00233 static uint64_t opaque_list_push(CHDContext *priv, uint64_t reordered_opaque,
00234 uint8_t pic_type)
00235 {
00236 OpaqueList *newNode = av_mallocz(sizeof (OpaqueList));
00237 if (!newNode) {
00238 av_log(priv->avctx, AV_LOG_ERROR,
00239 "Unable to allocate new node in OpaqueList.\n");
00240 return 0;
00241 }
00242 if (!priv->head) {
00243 newNode->fake_timestamp = TIMESTAMP_UNIT;
00244 priv->head = newNode;
00245 } else {
00246 newNode->fake_timestamp = priv->tail->fake_timestamp + TIMESTAMP_UNIT;
00247 priv->tail->next = newNode;
00248 }
00249 priv->tail = newNode;
00250 newNode->reordered_opaque = reordered_opaque;
00251 newNode->pic_type = pic_type;
00252
00253 return newNode->fake_timestamp;
00254 }
00255
00256
00257
00258
00259
00260
00261
00262
00263 static OpaqueList *opaque_list_pop(CHDContext *priv, uint64_t fake_timestamp)
00264 {
00265 OpaqueList *node = priv->head;
00266
00267 if (!priv->head) {
00268 av_log(priv->avctx, AV_LOG_ERROR,
00269 "CrystalHD: Attempted to query non-existent timestamps.\n");
00270 return NULL;
00271 }
00272
00273
00274
00275
00276
00277 if (priv->head->fake_timestamp == fake_timestamp) {
00278 priv->head = node->next;
00279
00280 if (!priv->head->next)
00281 priv->tail = priv->head;
00282
00283 node->next = NULL;
00284 return node;
00285 }
00286
00287
00288
00289
00290
00291 while (node->next) {
00292 OpaqueList *current = node->next;
00293 if (current->fake_timestamp == fake_timestamp) {
00294 node->next = current->next;
00295
00296 if (!node->next)
00297 priv->tail = node;
00298
00299 current->next = NULL;
00300 return current;
00301 } else {
00302 node = current;
00303 }
00304 }
00305
00306 av_log(priv->avctx, AV_LOG_VERBOSE,
00307 "CrystalHD: Couldn't match fake_timestamp.\n");
00308 return NULL;
00309 }
00310
00311
00312
00313
00314
00315
00316 static void flush(AVCodecContext *avctx)
00317 {
00318 CHDContext *priv = avctx->priv_data;
00319
00320 avctx->has_b_frames = 0;
00321 priv->last_picture = -1;
00322 priv->output_ready = 0;
00323 priv->need_second_field = 0;
00324 priv->skip_next_output = 0;
00325 priv->decode_wait = BASE_WAIT;
00326
00327 if (priv->pic.data[0])
00328 avctx->release_buffer(avctx, &priv->pic);
00329
00330
00331 DtsFlushInput(priv->dev, 4);
00332 }
00333
00334
00335 static av_cold int uninit(AVCodecContext *avctx)
00336 {
00337 CHDContext *priv = avctx->priv_data;
00338 HANDLE device;
00339
00340 device = priv->dev;
00341 DtsStopDecoder(device);
00342 DtsCloseDecoder(device);
00343 DtsDeviceClose(device);
00344
00345
00346
00347
00348
00349
00350 if (priv->orig_extradata) {
00351 av_free(avctx->extradata);
00352 avctx->extradata = priv->orig_extradata;
00353 avctx->extradata_size = priv->orig_extradata_size;
00354 priv->orig_extradata = NULL;
00355 priv->orig_extradata_size = 0;
00356 }
00357
00358 av_parser_close(priv->parser);
00359 if (priv->bsfc) {
00360 av_bitstream_filter_close(priv->bsfc);
00361 }
00362
00363 av_free(priv->sps_pps_buf);
00364
00365 if (priv->pic.data[0])
00366 avctx->release_buffer(avctx, &priv->pic);
00367
00368 if (priv->head) {
00369 OpaqueList *node = priv->head;
00370 while (node) {
00371 OpaqueList *next = node->next;
00372 av_free(node);
00373 node = next;
00374 }
00375 }
00376
00377 return 0;
00378 }
00379
00380
00381 static av_cold int init(AVCodecContext *avctx)
00382 {
00383 CHDContext* priv;
00384 BC_STATUS ret;
00385 BC_INFO_CRYSTAL version;
00386 BC_INPUT_FORMAT format = {
00387 .FGTEnable = FALSE,
00388 .Progressive = TRUE,
00389 .OptFlags = 0x80000000 | vdecFrameRate59_94 | 0x40,
00390 .width = avctx->width,
00391 .height = avctx->height,
00392 };
00393
00394 BC_MEDIA_SUBTYPE subtype;
00395
00396 uint32_t mode = DTS_PLAYBACK_MODE |
00397 DTS_LOAD_FILE_PLAY_FW |
00398 DTS_SKIP_TX_CHK_CPB |
00399 DTS_PLAYBACK_DROP_RPT_MODE |
00400 DTS_SINGLE_THREADED_MODE |
00401 DTS_DFLT_RESOLUTION(vdecRESOLUTION_1080p23_976);
00402
00403 av_log(avctx, AV_LOG_VERBOSE, "CrystalHD Init for %s\n",
00404 avctx->codec->name);
00405
00406 avctx->pix_fmt = AV_PIX_FMT_YUYV422;
00407
00408
00409 priv = avctx->priv_data;
00410 priv->avctx = avctx;
00411 priv->is_nal = avctx->extradata_size > 0 && *(avctx->extradata) == 1;
00412 priv->last_picture = -1;
00413 priv->decode_wait = BASE_WAIT;
00414
00415 subtype = id2subtype(priv, avctx->codec->id);
00416 switch (subtype) {
00417 case BC_MSUBTYPE_AVC1:
00418 {
00419 uint8_t *dummy_p;
00420 int dummy_int;
00421
00422
00423 priv->orig_extradata = av_malloc(avctx->extradata_size);
00424 if (!priv->orig_extradata) {
00425 av_log(avctx, AV_LOG_ERROR,
00426 "Failed to allocate copy of extradata\n");
00427 return AVERROR(ENOMEM);
00428 }
00429 priv->orig_extradata_size = avctx->extradata_size;
00430 memcpy(priv->orig_extradata, avctx->extradata, avctx->extradata_size);
00431
00432 priv->bsfc = av_bitstream_filter_init("h264_mp4toannexb");
00433 if (!priv->bsfc) {
00434 av_log(avctx, AV_LOG_ERROR,
00435 "Cannot open the h264_mp4toannexb BSF!\n");
00436 return AVERROR_BSF_NOT_FOUND;
00437 }
00438 av_bitstream_filter_filter(priv->bsfc, avctx, NULL, &dummy_p,
00439 &dummy_int, NULL, 0, 0);
00440 }
00441 subtype = BC_MSUBTYPE_H264;
00442
00443 case BC_MSUBTYPE_H264:
00444 format.startCodeSz = 4;
00445
00446 case BC_MSUBTYPE_VC1:
00447 case BC_MSUBTYPE_WVC1:
00448 case BC_MSUBTYPE_WMV3:
00449 case BC_MSUBTYPE_WMVA:
00450 case BC_MSUBTYPE_MPEG2VIDEO:
00451 case BC_MSUBTYPE_DIVX:
00452 case BC_MSUBTYPE_DIVX311:
00453 format.pMetaData = avctx->extradata;
00454 format.metaDataSz = avctx->extradata_size;
00455 break;
00456 default:
00457 av_log(avctx, AV_LOG_ERROR, "CrystalHD: Unknown codec name\n");
00458 return AVERROR(EINVAL);
00459 }
00460 format.mSubtype = subtype;
00461
00462 if (priv->sWidth) {
00463 format.bEnableScaling = 1;
00464 format.ScalingParams.sWidth = priv->sWidth;
00465 }
00466
00467
00468 av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: starting up\n");
00469
00470 ret = DtsDeviceOpen(&priv->dev, mode);
00471 if (ret != BC_STS_SUCCESS) {
00472 av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: DtsDeviceOpen failed\n");
00473 goto fail;
00474 }
00475
00476 ret = DtsCrystalHDVersion(priv->dev, &version);
00477 if (ret != BC_STS_SUCCESS) {
00478 av_log(avctx, AV_LOG_VERBOSE,
00479 "CrystalHD: DtsCrystalHDVersion failed\n");
00480 goto fail;
00481 }
00482 priv->is_70012 = version.device == 0;
00483
00484 if (priv->is_70012 &&
00485 (subtype == BC_MSUBTYPE_DIVX || subtype == BC_MSUBTYPE_DIVX311)) {
00486 av_log(avctx, AV_LOG_VERBOSE,
00487 "CrystalHD: BCM70012 doesn't support MPEG4-ASP/DivX/Xvid\n");
00488 goto fail;
00489 }
00490
00491 ret = DtsSetInputFormat(priv->dev, &format);
00492 if (ret != BC_STS_SUCCESS) {
00493 av_log(avctx, AV_LOG_ERROR, "CrystalHD: SetInputFormat failed\n");
00494 goto fail;
00495 }
00496
00497 ret = DtsOpenDecoder(priv->dev, BC_STREAM_TYPE_ES);
00498 if (ret != BC_STS_SUCCESS) {
00499 av_log(avctx, AV_LOG_ERROR, "CrystalHD: DtsOpenDecoder failed\n");
00500 goto fail;
00501 }
00502
00503 ret = DtsSetColorSpace(priv->dev, OUTPUT_MODE422_YUY2);
00504 if (ret != BC_STS_SUCCESS) {
00505 av_log(avctx, AV_LOG_ERROR, "CrystalHD: DtsSetColorSpace failed\n");
00506 goto fail;
00507 }
00508 ret = DtsStartDecoder(priv->dev);
00509 if (ret != BC_STS_SUCCESS) {
00510 av_log(avctx, AV_LOG_ERROR, "CrystalHD: DtsStartDecoder failed\n");
00511 goto fail;
00512 }
00513 ret = DtsStartCapture(priv->dev);
00514 if (ret != BC_STS_SUCCESS) {
00515 av_log(avctx, AV_LOG_ERROR, "CrystalHD: DtsStartCapture failed\n");
00516 goto fail;
00517 }
00518
00519 if (avctx->codec->id == AV_CODEC_ID_H264) {
00520 priv->parser = av_parser_init(avctx->codec->id);
00521 if (!priv->parser)
00522 av_log(avctx, AV_LOG_WARNING,
00523 "Cannot open the h.264 parser! Interlaced h.264 content "
00524 "will not be detected reliably.\n");
00525 priv->parser->flags = PARSER_FLAG_COMPLETE_FRAMES;
00526 }
00527 av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: Init complete.\n");
00528
00529 return 0;
00530
00531 fail:
00532 uninit(avctx);
00533 return -1;
00534 }
00535
00536
00537 static inline CopyRet copy_frame(AVCodecContext *avctx,
00538 BC_DTS_PROC_OUT *output,
00539 void *data, int *got_frame)
00540 {
00541 BC_STATUS ret;
00542 BC_DTS_STATUS decoder_status = { 0, };
00543 uint8_t trust_interlaced;
00544 uint8_t interlaced;
00545
00546 CHDContext *priv = avctx->priv_data;
00547 int64_t pkt_pts = AV_NOPTS_VALUE;
00548 uint8_t pic_type = 0;
00549
00550 uint8_t bottom_field = (output->PicInfo.flags & VDEC_FLAG_BOTTOMFIELD) ==
00551 VDEC_FLAG_BOTTOMFIELD;
00552 uint8_t bottom_first = !!(output->PicInfo.flags & VDEC_FLAG_BOTTOM_FIRST);
00553
00554 int width = output->PicInfo.width;
00555 int height = output->PicInfo.height;
00556 int bwidth;
00557 uint8_t *src = output->Ybuff;
00558 int sStride;
00559 uint8_t *dst;
00560 int dStride;
00561
00562 if (output->PicInfo.timeStamp != 0) {
00563 OpaqueList *node = opaque_list_pop(priv, output->PicInfo.timeStamp);
00564 if (node) {
00565 pkt_pts = node->reordered_opaque;
00566 pic_type = node->pic_type;
00567 av_free(node);
00568 } else {
00569
00570
00571
00572
00573
00574
00575
00576
00577 pic_type = PICT_BOTTOM_FIELD;
00578 }
00579 av_log(avctx, AV_LOG_VERBOSE, "output \"pts\": %"PRIu64"\n",
00580 output->PicInfo.timeStamp);
00581 av_log(avctx, AV_LOG_VERBOSE, "output picture type %d\n",
00582 pic_type);
00583 }
00584
00585 ret = DtsGetDriverStatus(priv->dev, &decoder_status);
00586 if (ret != BC_STS_SUCCESS) {
00587 av_log(avctx, AV_LOG_ERROR,
00588 "CrystalHD: GetDriverStatus failed: %u\n", ret);
00589 return RET_ERROR;
00590 }
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608 trust_interlaced = avctx->codec->id != AV_CODEC_ID_H264 ||
00609 !(output->PicInfo.flags & VDEC_FLAG_UNKNOWN_SRC) ||
00610 priv->need_second_field ||
00611 (decoder_status.picNumFlags & ~0x40000000) ==
00612 output->PicInfo.picture_number;
00613
00614
00615
00616
00617
00618
00619
00620 if (output->PicInfo.picture_number == priv->last_picture && !priv->need_second_field) {
00621 av_log(avctx, AV_LOG_WARNING,
00622 "Incorrectly guessed progressive frame. Discarding second field\n");
00623
00624 return RET_OK;
00625 }
00626
00627 interlaced = (output->PicInfo.flags & VDEC_FLAG_INTERLACED_SRC) &&
00628 trust_interlaced;
00629
00630 if (!trust_interlaced && (decoder_status.picNumFlags & ~0x40000000) == 0) {
00631 av_log(avctx, AV_LOG_VERBOSE,
00632 "Next picture number unknown. Assuming progressive frame.\n");
00633 }
00634
00635 av_log(avctx, AV_LOG_VERBOSE, "Interlaced state: %d | trust_interlaced %d\n",
00636 interlaced, trust_interlaced);
00637
00638 if (priv->pic.data[0] && !priv->need_second_field)
00639 avctx->release_buffer(avctx, &priv->pic);
00640
00641 priv->need_second_field = interlaced && !priv->need_second_field;
00642
00643 priv->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE |
00644 FF_BUFFER_HINTS_REUSABLE;
00645 if (!priv->pic.data[0]) {
00646 if (ff_get_buffer(avctx, &priv->pic) < 0) {
00647 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00648 return RET_ERROR;
00649 }
00650 }
00651
00652 bwidth = av_image_get_linesize(avctx->pix_fmt, width, 0);
00653 if (priv->is_70012) {
00654 int pStride;
00655
00656 if (width <= 720)
00657 pStride = 720;
00658 else if (width <= 1280)
00659 pStride = 1280;
00660 else pStride = 1920;
00661 sStride = av_image_get_linesize(avctx->pix_fmt, pStride, 0);
00662 } else {
00663 sStride = bwidth;
00664 }
00665
00666 dStride = priv->pic.linesize[0];
00667 dst = priv->pic.data[0];
00668
00669 av_log(priv->avctx, AV_LOG_VERBOSE, "CrystalHD: Copying out frame\n");
00670
00671 if (interlaced) {
00672 int dY = 0;
00673 int sY = 0;
00674
00675 height /= 2;
00676 if (bottom_field) {
00677 av_log(priv->avctx, AV_LOG_VERBOSE, "Interlaced: bottom field\n");
00678 dY = 1;
00679 } else {
00680 av_log(priv->avctx, AV_LOG_VERBOSE, "Interlaced: top field\n");
00681 dY = 0;
00682 }
00683
00684 for (sY = 0; sY < height; dY++, sY++) {
00685 memcpy(&(dst[dY * dStride]), &(src[sY * sStride]), bwidth);
00686 dY++;
00687 }
00688 } else {
00689 av_image_copy_plane(dst, dStride, src, sStride, bwidth, height);
00690 }
00691
00692 priv->pic.interlaced_frame = interlaced;
00693 if (interlaced)
00694 priv->pic.top_field_first = !bottom_first;
00695
00696 priv->pic.pkt_pts = pkt_pts;
00697
00698 if (!priv->need_second_field) {
00699 *got_frame = 1;
00700 *(AVFrame *)data = priv->pic;
00701 }
00702
00703
00704
00705
00706
00707
00708
00709
00710 if (!interlaced && (output->PicInfo.flags & VDEC_FLAG_UNKNOWN_SRC) &&
00711 (pic_type == PICT_TOP_FIELD || pic_type == PICT_BOTTOM_FIELD)) {
00712 av_log(priv->avctx, AV_LOG_VERBOSE, "Fieldpair from two packets.\n");
00713 return RET_SKIP_NEXT_COPY;
00714 }
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728 return priv->need_second_field &&
00729 (!(output->PicInfo.flags & VDEC_FLAG_UNKNOWN_SRC) ||
00730 pic_type == PICT_FRAME) ?
00731 RET_COPY_NEXT_FIELD : RET_OK;
00732 }
00733
00734
00735 static inline CopyRet receive_frame(AVCodecContext *avctx,
00736 void *data, int *got_frame)
00737 {
00738 BC_STATUS ret;
00739 BC_DTS_PROC_OUT output = {
00740 .PicInfo.width = avctx->width,
00741 .PicInfo.height = avctx->height,
00742 };
00743 CHDContext *priv = avctx->priv_data;
00744 HANDLE dev = priv->dev;
00745
00746 *got_frame = 0;
00747
00748
00749 ret = DtsProcOutputNoCopy(dev, OUTPUT_PROC_TIMEOUT, &output);
00750 if (ret == BC_STS_FMT_CHANGE) {
00751 av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: Initial format change\n");
00752 avctx->width = output.PicInfo.width;
00753 avctx->height = output.PicInfo.height;
00754 switch ( output.PicInfo.aspect_ratio ) {
00755 case vdecAspectRatioSquare:
00756 avctx->sample_aspect_ratio = (AVRational) { 1, 1};
00757 break;
00758 case vdecAspectRatio12_11:
00759 avctx->sample_aspect_ratio = (AVRational) { 12, 11};
00760 break;
00761 case vdecAspectRatio10_11:
00762 avctx->sample_aspect_ratio = (AVRational) { 10, 11};
00763 break;
00764 case vdecAspectRatio16_11:
00765 avctx->sample_aspect_ratio = (AVRational) { 16, 11};
00766 break;
00767 case vdecAspectRatio40_33:
00768 avctx->sample_aspect_ratio = (AVRational) { 40, 33};
00769 break;
00770 case vdecAspectRatio24_11:
00771 avctx->sample_aspect_ratio = (AVRational) { 24, 11};
00772 break;
00773 case vdecAspectRatio20_11:
00774 avctx->sample_aspect_ratio = (AVRational) { 20, 11};
00775 break;
00776 case vdecAspectRatio32_11:
00777 avctx->sample_aspect_ratio = (AVRational) { 32, 11};
00778 break;
00779 case vdecAspectRatio80_33:
00780 avctx->sample_aspect_ratio = (AVRational) { 80, 33};
00781 break;
00782 case vdecAspectRatio18_11:
00783 avctx->sample_aspect_ratio = (AVRational) { 18, 11};
00784 break;
00785 case vdecAspectRatio15_11:
00786 avctx->sample_aspect_ratio = (AVRational) { 15, 11};
00787 break;
00788 case vdecAspectRatio64_33:
00789 avctx->sample_aspect_ratio = (AVRational) { 64, 33};
00790 break;
00791 case vdecAspectRatio160_99:
00792 avctx->sample_aspect_ratio = (AVRational) {160, 99};
00793 break;
00794 case vdecAspectRatio4_3:
00795 avctx->sample_aspect_ratio = (AVRational) { 4, 3};
00796 break;
00797 case vdecAspectRatio16_9:
00798 avctx->sample_aspect_ratio = (AVRational) { 16, 9};
00799 break;
00800 case vdecAspectRatio221_1:
00801 avctx->sample_aspect_ratio = (AVRational) {221, 1};
00802 break;
00803 }
00804 return RET_COPY_AGAIN;
00805 } else if (ret == BC_STS_SUCCESS) {
00806 int copy_ret = -1;
00807 if (output.PoutFlags & BC_POUT_FLAGS_PIB_VALID) {
00808 if (priv->last_picture == -1) {
00809
00810
00811
00812
00813 priv->last_picture = output.PicInfo.picture_number - 1;
00814 }
00815
00816 if (avctx->codec->id == AV_CODEC_ID_MPEG4 &&
00817 output.PicInfo.timeStamp == 0 && priv->bframe_bug) {
00818 av_log(avctx, AV_LOG_VERBOSE,
00819 "CrystalHD: Not returning packed frame twice.\n");
00820 priv->last_picture++;
00821 DtsReleaseOutputBuffs(dev, NULL, FALSE);
00822 return RET_COPY_AGAIN;
00823 }
00824
00825 print_frame_info(priv, &output);
00826
00827 if (priv->last_picture + 1 < output.PicInfo.picture_number) {
00828 av_log(avctx, AV_LOG_WARNING,
00829 "CrystalHD: Picture Number discontinuity\n");
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840 priv->last_picture = output.PicInfo.picture_number - 1;
00841 }
00842
00843 copy_ret = copy_frame(avctx, &output, data, got_frame);
00844 if (*got_frame > 0) {
00845 avctx->has_b_frames--;
00846 priv->last_picture++;
00847 av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: Pipeline length: %u\n",
00848 avctx->has_b_frames);
00849 }
00850 } else {
00851
00852
00853
00854 av_log(avctx, AV_LOG_ERROR, "CrystalHD: ProcOutput succeeded with "
00855 "invalid PIB\n");
00856 avctx->has_b_frames--;
00857 copy_ret = RET_OK;
00858 }
00859 DtsReleaseOutputBuffs(dev, NULL, FALSE);
00860
00861 return copy_ret;
00862 } else if (ret == BC_STS_BUSY) {
00863 return RET_COPY_AGAIN;
00864 } else {
00865 av_log(avctx, AV_LOG_ERROR, "CrystalHD: ProcOutput failed %d\n", ret);
00866 return RET_ERROR;
00867 }
00868 }
00869
00870
00871 static int decode(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
00872 {
00873 BC_STATUS ret;
00874 BC_DTS_STATUS decoder_status = { 0, };
00875 CopyRet rec_ret;
00876 CHDContext *priv = avctx->priv_data;
00877 HANDLE dev = priv->dev;
00878 uint8_t *in_data = avpkt->data;
00879 int len = avpkt->size;
00880 int free_data = 0;
00881 uint8_t pic_type = 0;
00882
00883 av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: decode_frame\n");
00884
00885 if (avpkt->size == 7 && !priv->bframe_bug) {
00886
00887
00888
00889 av_log(avctx, AV_LOG_INFO,
00890 "CrystalHD: Enabling work-around for packed b-frame bug\n");
00891 priv->bframe_bug = 1;
00892 } else if (avpkt->size == 8 && priv->bframe_bug) {
00893
00894
00895
00896 av_log(avctx, AV_LOG_INFO,
00897 "CrystalHD: Disabling work-around for packed b-frame bug\n");
00898 priv->bframe_bug = 0;
00899 }
00900
00901 if (len) {
00902 int32_t tx_free = (int32_t)DtsTxFreeSize(dev);
00903
00904 if (priv->parser) {
00905 int ret = 0;
00906
00907 if (priv->bsfc) {
00908 ret = av_bitstream_filter_filter(priv->bsfc, avctx, NULL,
00909 &in_data, &len,
00910 avpkt->data, len, 0);
00911 }
00912 free_data = ret > 0;
00913
00914 if (ret >= 0) {
00915 uint8_t *pout;
00916 int psize;
00917 int index;
00918 H264Context *h = priv->parser->priv_data;
00919
00920 index = av_parser_parse2(priv->parser, avctx, &pout, &psize,
00921 in_data, len, avctx->pkt->pts,
00922 avctx->pkt->dts, 0);
00923 if (index < 0) {
00924 av_log(avctx, AV_LOG_WARNING,
00925 "CrystalHD: Failed to parse h.264 packet to "
00926 "detect interlacing.\n");
00927 } else if (index != len) {
00928 av_log(avctx, AV_LOG_WARNING,
00929 "CrystalHD: Failed to parse h.264 packet "
00930 "completely. Interlaced frames may be "
00931 "incorrectly detected.\n");
00932 } else {
00933 av_log(avctx, AV_LOG_VERBOSE,
00934 "CrystalHD: parser picture type %d\n",
00935 h->s.picture_structure);
00936 pic_type = h->s.picture_structure;
00937 }
00938 } else {
00939 av_log(avctx, AV_LOG_WARNING,
00940 "CrystalHD: mp4toannexb filter failed to filter "
00941 "packet. Interlaced frames may be incorrectly "
00942 "detected.\n");
00943 }
00944 }
00945
00946 if (len < tx_free - 1024) {
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956 uint64_t pts = opaque_list_push(priv, avctx->pkt->pts, pic_type);
00957 if (!pts) {
00958 if (free_data) {
00959 av_freep(&in_data);
00960 }
00961 return AVERROR(ENOMEM);
00962 }
00963 av_log(priv->avctx, AV_LOG_VERBOSE,
00964 "input \"pts\": %"PRIu64"\n", pts);
00965 ret = DtsProcInput(dev, in_data, len, pts, 0);
00966 if (free_data) {
00967 av_freep(&in_data);
00968 }
00969 if (ret == BC_STS_BUSY) {
00970 av_log(avctx, AV_LOG_WARNING,
00971 "CrystalHD: ProcInput returned busy\n");
00972 usleep(BASE_WAIT);
00973 return AVERROR(EBUSY);
00974 } else if (ret != BC_STS_SUCCESS) {
00975 av_log(avctx, AV_LOG_ERROR,
00976 "CrystalHD: ProcInput failed: %u\n", ret);
00977 return -1;
00978 }
00979 avctx->has_b_frames++;
00980 } else {
00981 av_log(avctx, AV_LOG_WARNING, "CrystalHD: Input buffer full\n");
00982 len = 0;
00983 }
00984 } else {
00985 av_log(avctx, AV_LOG_INFO, "CrystalHD: No more input data\n");
00986 }
00987
00988 if (priv->skip_next_output) {
00989 av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: Skipping next output.\n");
00990 priv->skip_next_output = 0;
00991 avctx->has_b_frames--;
00992 return len;
00993 }
00994
00995 ret = DtsGetDriverStatus(dev, &decoder_status);
00996 if (ret != BC_STS_SUCCESS) {
00997 av_log(avctx, AV_LOG_ERROR, "CrystalHD: GetDriverStatus failed\n");
00998 return -1;
00999 }
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009 if (priv->output_ready < 2) {
01010 if (decoder_status.ReadyListCount != 0)
01011 priv->output_ready++;
01012 usleep(BASE_WAIT);
01013 av_log(avctx, AV_LOG_INFO, "CrystalHD: Filling pipeline.\n");
01014 return len;
01015 } else if (decoder_status.ReadyListCount == 0) {
01016
01017
01018
01019
01020
01021
01022 usleep(BASE_WAIT);
01023 priv->decode_wait += WAIT_UNIT;
01024 av_log(avctx, AV_LOG_INFO, "CrystalHD: No frames ready. Returning\n");
01025 return len;
01026 }
01027
01028 do {
01029 rec_ret = receive_frame(avctx, data, got_frame);
01030 if (rec_ret == RET_OK && *got_frame == 0) {
01031
01032
01033
01034
01035
01036
01037
01038 av_log(avctx, AV_LOG_VERBOSE, "Returning after first field.\n");
01039 avctx->has_b_frames--;
01040 } else if (rec_ret == RET_COPY_NEXT_FIELD) {
01041
01042
01043
01044
01045
01046
01047
01048
01049 av_log(avctx, AV_LOG_VERBOSE, "Trying to get second field.\n");
01050 while (1) {
01051 usleep(priv->decode_wait);
01052 ret = DtsGetDriverStatus(dev, &decoder_status);
01053 if (ret == BC_STS_SUCCESS &&
01054 decoder_status.ReadyListCount > 0) {
01055 rec_ret = receive_frame(avctx, data, got_frame);
01056 if ((rec_ret == RET_OK && *got_frame > 0) ||
01057 rec_ret == RET_ERROR)
01058 break;
01059 }
01060 }
01061 av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: Got second field.\n");
01062 } else if (rec_ret == RET_SKIP_NEXT_COPY) {
01063
01064
01065
01066 av_log(avctx, AV_LOG_VERBOSE,
01067 "Don't output on next decode call.\n");
01068 priv->skip_next_output = 1;
01069 }
01070
01071
01072
01073
01074
01075
01076
01077
01078 } while (rec_ret == RET_COPY_AGAIN);
01079 usleep(priv->decode_wait);
01080 return len;
01081 }
01082
01083
01084 #if CONFIG_H264_CRYSTALHD_DECODER
01085 static AVClass h264_class = {
01086 "h264_crystalhd",
01087 av_default_item_name,
01088 options,
01089 LIBAVUTIL_VERSION_INT,
01090 };
01091
01092 AVCodec ff_h264_crystalhd_decoder = {
01093 .name = "h264_crystalhd",
01094 .type = AVMEDIA_TYPE_VIDEO,
01095 .id = AV_CODEC_ID_H264,
01096 .priv_data_size = sizeof(CHDContext),
01097 .init = init,
01098 .close = uninit,
01099 .decode = decode,
01100 .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY,
01101 .flush = flush,
01102 .long_name = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (CrystalHD acceleration)"),
01103 .pix_fmts = (const enum AVPixelFormat[]){AV_PIX_FMT_YUYV422, AV_PIX_FMT_NONE},
01104 .priv_class = &h264_class,
01105 };
01106 #endif
01107
01108 #if CONFIG_MPEG2_CRYSTALHD_DECODER
01109 static AVClass mpeg2_class = {
01110 "mpeg2_crystalhd",
01111 av_default_item_name,
01112 options,
01113 LIBAVUTIL_VERSION_INT,
01114 };
01115
01116 AVCodec ff_mpeg2_crystalhd_decoder = {
01117 .name = "mpeg2_crystalhd",
01118 .type = AVMEDIA_TYPE_VIDEO,
01119 .id = AV_CODEC_ID_MPEG2VIDEO,
01120 .priv_data_size = sizeof(CHDContext),
01121 .init = init,
01122 .close = uninit,
01123 .decode = decode,
01124 .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY,
01125 .flush = flush,
01126 .long_name = NULL_IF_CONFIG_SMALL("MPEG-2 Video (CrystalHD acceleration)"),
01127 .pix_fmts = (const enum AVPixelFormat[]){AV_PIX_FMT_YUYV422, AV_PIX_FMT_NONE},
01128 .priv_class = &mpeg2_class,
01129 };
01130 #endif
01131
01132 #if CONFIG_MPEG4_CRYSTALHD_DECODER
01133 static AVClass mpeg4_class = {
01134 "mpeg4_crystalhd",
01135 av_default_item_name,
01136 options,
01137 LIBAVUTIL_VERSION_INT,
01138 };
01139
01140 AVCodec ff_mpeg4_crystalhd_decoder = {
01141 .name = "mpeg4_crystalhd",
01142 .type = AVMEDIA_TYPE_VIDEO,
01143 .id = AV_CODEC_ID_MPEG4,
01144 .priv_data_size = sizeof(CHDContext),
01145 .init = init,
01146 .close = uninit,
01147 .decode = decode,
01148 .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY,
01149 .flush = flush,
01150 .long_name = NULL_IF_CONFIG_SMALL("MPEG-4 Part 2 (CrystalHD acceleration)"),
01151 .pix_fmts = (const enum AVPixelFormat[]){AV_PIX_FMT_YUYV422, AV_PIX_FMT_NONE},
01152 .priv_class = &mpeg4_class,
01153 };
01154 #endif
01155
01156 #if CONFIG_MSMPEG4_CRYSTALHD_DECODER
01157 static AVClass msmpeg4_class = {
01158 "msmpeg4_crystalhd",
01159 av_default_item_name,
01160 options,
01161 LIBAVUTIL_VERSION_INT,
01162 };
01163
01164 AVCodec ff_msmpeg4_crystalhd_decoder = {
01165 .name = "msmpeg4_crystalhd",
01166 .type = AVMEDIA_TYPE_VIDEO,
01167 .id = AV_CODEC_ID_MSMPEG4V3,
01168 .priv_data_size = sizeof(CHDContext),
01169 .init = init,
01170 .close = uninit,
01171 .decode = decode,
01172 .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_EXPERIMENTAL,
01173 .flush = flush,
01174 .long_name = NULL_IF_CONFIG_SMALL("MPEG-4 Part 2 Microsoft variant version 3 (CrystalHD acceleration)"),
01175 .pix_fmts = (const enum AVPixelFormat[]){AV_PIX_FMT_YUYV422, AV_PIX_FMT_NONE},
01176 .priv_class = &msmpeg4_class,
01177 };
01178 #endif
01179
01180 #if CONFIG_VC1_CRYSTALHD_DECODER
01181 static AVClass vc1_class = {
01182 "vc1_crystalhd",
01183 av_default_item_name,
01184 options,
01185 LIBAVUTIL_VERSION_INT,
01186 };
01187
01188 AVCodec ff_vc1_crystalhd_decoder = {
01189 .name = "vc1_crystalhd",
01190 .type = AVMEDIA_TYPE_VIDEO,
01191 .id = AV_CODEC_ID_VC1,
01192 .priv_data_size = sizeof(CHDContext),
01193 .init = init,
01194 .close = uninit,
01195 .decode = decode,
01196 .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY,
01197 .flush = flush,
01198 .long_name = NULL_IF_CONFIG_SMALL("SMPTE VC-1 (CrystalHD acceleration)"),
01199 .pix_fmts = (const enum AVPixelFormat[]){AV_PIX_FMT_YUYV422, AV_PIX_FMT_NONE},
01200 .priv_class = &vc1_class,
01201 };
01202 #endif
01203
01204 #if CONFIG_WMV3_CRYSTALHD_DECODER
01205 static AVClass wmv3_class = {
01206 "wmv3_crystalhd",
01207 av_default_item_name,
01208 options,
01209 LIBAVUTIL_VERSION_INT,
01210 };
01211
01212 AVCodec ff_wmv3_crystalhd_decoder = {
01213 .name = "wmv3_crystalhd",
01214 .type = AVMEDIA_TYPE_VIDEO,
01215 .id = AV_CODEC_ID_WMV3,
01216 .priv_data_size = sizeof(CHDContext),
01217 .init = init,
01218 .close = uninit,
01219 .decode = decode,
01220 .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY,
01221 .flush = flush,
01222 .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9 (CrystalHD acceleration)"),
01223 .pix_fmts = (const enum AVPixelFormat[]){AV_PIX_FMT_YUYV422, AV_PIX_FMT_NONE},
01224 .priv_class = &wmv3_class,
01225 };
01226 #endif