You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

964 lines
31KB

  1. /*
  2. * - CrystalHD decoder module -
  3. *
  4. * Copyright(C) 2010,2011 Philip Langdale <ffmpeg.philipl@overt.org>
  5. *
  6. * This file is part of FFmpeg.
  7. *
  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.
  12. *
  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.
  17. *
  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
  21. */
  22. /*
  23. * - Principles of Operation -
  24. *
  25. * The CrystalHD decoder operates at the bitstream level - which is an even
  26. * higher level than the decoding hardware you typically see in modern GPUs.
  27. * This means it has a very simple interface, in principle. You feed demuxed
  28. * packets in one end and get decoded picture (fields/frames) out the other.
  29. *
  30. * Of course, nothing is ever that simple. Due, at the very least, to b-frame
  31. * dependencies in the supported formats, the hardware has a delay between
  32. * when a packet goes in, and when a picture comes out. Furthermore, this delay
  33. * is not just a function of time, but also one of the dependency on additional
  34. * frames being fed into the decoder to satisfy the b-frame dependencies.
  35. *
  36. * As such, a pipeline will build up that is roughly equivalent to the required
  37. * DPB for the file being played. If that was all it took, things would still
  38. * be simple - so, of course, it isn't.
  39. *
  40. * The hardware has a way of indicating that a picture is ready to be copied out,
  41. * but this is unreliable - and sometimes the attempt will still fail so, based
  42. * on testing, the code will wait until 3 pictures are ready before starting
  43. * to copy out - and this has the effect of extending the pipeline.
  44. *
  45. * Finally, while it is tempting to say that once the decoder starts outputting
  46. * frames, the software should never fail to return a frame from a decode(),
  47. * this is a hard assertion to make, because the stream may switch between
  48. * differently encoded content (number of b-frames, interlacing, etc) which
  49. * might require a longer pipeline than before. If that happened, you could
  50. * deadlock trying to retrieve a frame that can't be decoded without feeding
  51. * in additional packets.
  52. *
  53. * As such, the code will return in the event that a picture cannot be copied
  54. * out, leading to an increase in the length of the pipeline. This in turn,
  55. * means we have to be sensitive to the time it takes to decode a picture;
  56. * We do not want to give up just because the hardware needed a little more
  57. * time to prepare the picture! For this reason, there are delays included
  58. * in the decode() path that ensure that, under normal conditions, the hardware
  59. * will only fail to return a frame if it really needs additional packets to
  60. * complete the decoding.
  61. *
  62. * Finally, to be explicit, we do not want the pipeline to grow without bound
  63. * for two reasons: 1) The hardware can only buffer a finite number of packets,
  64. * and 2) The client application may not be able to cope with arbitrarily long
  65. * delays in the video path relative to the audio path. For example. MPlayer
  66. * can only handle a 20 picture delay (although this is arbitrary, and needs
  67. * to be extended to fully support the CrystalHD where the delay could be up
  68. * to 32 pictures - consider PAFF H.264 content with 16 b-frames).
  69. */
  70. /*****************************************************************************
  71. * Includes
  72. ****************************************************************************/
  73. #define _XOPEN_SOURCE 600
  74. #include <inttypes.h>
  75. #include <stdio.h>
  76. #include <stdlib.h>
  77. #include <libcrystalhd/bc_dts_types.h>
  78. #include <libcrystalhd/bc_dts_defs.h>
  79. #include <libcrystalhd/libcrystalhd_if.h>
  80. #include "avcodec.h"
  81. #include "internal.h"
  82. #include "libavutil/imgutils.h"
  83. #include "libavutil/intreadwrite.h"
  84. #include "libavutil/opt.h"
  85. #if HAVE_UNISTD_H
  86. #include <unistd.h>
  87. #endif
  88. /** Timeout parameter passed to DtsProcOutput() in us */
  89. #define OUTPUT_PROC_TIMEOUT 50
  90. /** Step between fake timestamps passed to hardware in units of 100ns */
  91. #define TIMESTAMP_UNIT 100000
  92. /*****************************************************************************
  93. * Module private data
  94. ****************************************************************************/
  95. typedef enum {
  96. RET_ERROR = -1,
  97. RET_OK = 0,
  98. } CopyRet;
  99. typedef struct OpaqueList {
  100. struct OpaqueList *next;
  101. uint64_t fake_timestamp;
  102. uint64_t reordered_opaque;
  103. } OpaqueList;
  104. typedef struct {
  105. AVClass *av_class;
  106. AVCodecContext *avctx;
  107. AVFrame *pic;
  108. HANDLE dev;
  109. uint8_t *orig_extradata;
  110. uint32_t orig_extradata_size;
  111. AVBSFContext *bsfc;
  112. uint8_t is_70012;
  113. uint8_t *sps_pps_buf;
  114. uint32_t sps_pps_size;
  115. uint8_t is_nal;
  116. uint8_t need_second_field;
  117. OpaqueList *head;
  118. OpaqueList *tail;
  119. /* Options */
  120. uint32_t sWidth;
  121. uint8_t bframe_bug;
  122. } CHDContext;
  123. static const AVOption options[] = {
  124. { "crystalhd_downscale_width",
  125. "Turn on downscaling to the specified width",
  126. offsetof(CHDContext, sWidth),
  127. AV_OPT_TYPE_INT, {.i64 = 0}, 0, UINT32_MAX,
  128. AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM, },
  129. { NULL, },
  130. };
  131. /*****************************************************************************
  132. * Helper functions
  133. ****************************************************************************/
  134. static inline BC_MEDIA_SUBTYPE id2subtype(CHDContext *priv, enum AVCodecID id)
  135. {
  136. switch (id) {
  137. case AV_CODEC_ID_MPEG4:
  138. return BC_MSUBTYPE_DIVX;
  139. case AV_CODEC_ID_MSMPEG4V3:
  140. return BC_MSUBTYPE_DIVX311;
  141. case AV_CODEC_ID_MPEG2VIDEO:
  142. return BC_MSUBTYPE_MPEG2VIDEO;
  143. case AV_CODEC_ID_VC1:
  144. return BC_MSUBTYPE_VC1;
  145. case AV_CODEC_ID_WMV3:
  146. return BC_MSUBTYPE_WMV3;
  147. case AV_CODEC_ID_H264:
  148. return priv->is_nal ? BC_MSUBTYPE_AVC1 : BC_MSUBTYPE_H264;
  149. default:
  150. return BC_MSUBTYPE_INVALID;
  151. }
  152. }
  153. static inline void print_frame_info(CHDContext *priv, BC_DTS_PROC_OUT *output)
  154. {
  155. av_log(priv->avctx, AV_LOG_TRACE, "\tYBuffSz: %u\n", output->YbuffSz);
  156. av_log(priv->avctx, AV_LOG_TRACE, "\tYBuffDoneSz: %u\n",
  157. output->YBuffDoneSz);
  158. av_log(priv->avctx, AV_LOG_TRACE, "\tUVBuffDoneSz: %u\n",
  159. output->UVBuffDoneSz);
  160. av_log(priv->avctx, AV_LOG_TRACE, "\tTimestamp: %"PRIu64"\n",
  161. output->PicInfo.timeStamp);
  162. av_log(priv->avctx, AV_LOG_TRACE, "\tPicture Number: %u\n",
  163. output->PicInfo.picture_number);
  164. av_log(priv->avctx, AV_LOG_TRACE, "\tWidth: %u\n",
  165. output->PicInfo.width);
  166. av_log(priv->avctx, AV_LOG_TRACE, "\tHeight: %u\n",
  167. output->PicInfo.height);
  168. av_log(priv->avctx, AV_LOG_TRACE, "\tChroma: 0x%03x\n",
  169. output->PicInfo.chroma_format);
  170. av_log(priv->avctx, AV_LOG_TRACE, "\tPulldown: %u\n",
  171. output->PicInfo.pulldown);
  172. av_log(priv->avctx, AV_LOG_TRACE, "\tFlags: 0x%08x\n",
  173. output->PicInfo.flags);
  174. av_log(priv->avctx, AV_LOG_TRACE, "\tFrame Rate/Res: %u\n",
  175. output->PicInfo.frame_rate);
  176. av_log(priv->avctx, AV_LOG_TRACE, "\tAspect Ratio: %u\n",
  177. output->PicInfo.aspect_ratio);
  178. av_log(priv->avctx, AV_LOG_TRACE, "\tColor Primaries: %u\n",
  179. output->PicInfo.colour_primaries);
  180. av_log(priv->avctx, AV_LOG_TRACE, "\tMetaData: %u\n",
  181. output->PicInfo.picture_meta_payload);
  182. av_log(priv->avctx, AV_LOG_TRACE, "\tSession Number: %u\n",
  183. output->PicInfo.sess_num);
  184. av_log(priv->avctx, AV_LOG_TRACE, "\tycom: %u\n",
  185. output->PicInfo.ycom);
  186. av_log(priv->avctx, AV_LOG_TRACE, "\tCustom Aspect: %u\n",
  187. output->PicInfo.custom_aspect_ratio_width_height);
  188. av_log(priv->avctx, AV_LOG_TRACE, "\tFrames to Drop: %u\n",
  189. output->PicInfo.n_drop);
  190. av_log(priv->avctx, AV_LOG_TRACE, "\tH264 Valid Fields: 0x%08x\n",
  191. output->PicInfo.other.h264.valid);
  192. }
  193. /*****************************************************************************
  194. * OpaqueList functions
  195. ****************************************************************************/
  196. static uint64_t opaque_list_push(CHDContext *priv, uint64_t reordered_opaque)
  197. {
  198. OpaqueList *newNode = av_mallocz(sizeof (OpaqueList));
  199. if (!newNode) {
  200. av_log(priv->avctx, AV_LOG_ERROR,
  201. "Unable to allocate new node in OpaqueList.\n");
  202. return 0;
  203. }
  204. if (!priv->head) {
  205. newNode->fake_timestamp = TIMESTAMP_UNIT;
  206. priv->head = newNode;
  207. } else {
  208. newNode->fake_timestamp = priv->tail->fake_timestamp + TIMESTAMP_UNIT;
  209. priv->tail->next = newNode;
  210. }
  211. priv->tail = newNode;
  212. newNode->reordered_opaque = reordered_opaque;
  213. return newNode->fake_timestamp;
  214. }
  215. /*
  216. * The OpaqueList is built in decode order, while elements will be removed
  217. * in presentation order. If frames are reordered, this means we must be
  218. * able to remove elements that are not the first element.
  219. *
  220. * Returned node must be freed by caller.
  221. */
  222. static OpaqueList *opaque_list_pop(CHDContext *priv, uint64_t fake_timestamp)
  223. {
  224. OpaqueList *node = priv->head;
  225. if (!priv->head) {
  226. av_log(priv->avctx, AV_LOG_ERROR,
  227. "CrystalHD: Attempted to query non-existent timestamps.\n");
  228. return NULL;
  229. }
  230. /*
  231. * The first element is special-cased because we have to manipulate
  232. * the head pointer rather than the previous element in the list.
  233. */
  234. if (priv->head->fake_timestamp == fake_timestamp) {
  235. priv->head = node->next;
  236. if (!priv->head->next)
  237. priv->tail = priv->head;
  238. node->next = NULL;
  239. return node;
  240. }
  241. /*
  242. * The list is processed at arm's length so that we have the
  243. * previous element available to rewrite its next pointer.
  244. */
  245. while (node->next) {
  246. OpaqueList *current = node->next;
  247. if (current->fake_timestamp == fake_timestamp) {
  248. node->next = current->next;
  249. if (!node->next)
  250. priv->tail = node;
  251. current->next = NULL;
  252. return current;
  253. } else {
  254. node = current;
  255. }
  256. }
  257. av_log(priv->avctx, AV_LOG_VERBOSE,
  258. "CrystalHD: Couldn't match fake_timestamp.\n");
  259. return NULL;
  260. }
  261. /*****************************************************************************
  262. * Video decoder API function definitions
  263. ****************************************************************************/
  264. static void flush(AVCodecContext *avctx)
  265. {
  266. CHDContext *priv = avctx->priv_data;
  267. priv->need_second_field = 0;
  268. av_frame_unref (priv->pic);
  269. /* Flush mode 4 flushes all software and hardware buffers. */
  270. DtsFlushInput(priv->dev, 4);
  271. }
  272. static av_cold int uninit(AVCodecContext *avctx)
  273. {
  274. CHDContext *priv = avctx->priv_data;
  275. HANDLE device;
  276. device = priv->dev;
  277. DtsStopDecoder(device);
  278. DtsCloseDecoder(device);
  279. DtsDeviceClose(device);
  280. /*
  281. * Restore original extradata, so that if the decoder is
  282. * reinitialised, the bitstream detection and filtering
  283. * will work as expected.
  284. */
  285. if (priv->orig_extradata) {
  286. av_free(avctx->extradata);
  287. avctx->extradata = priv->orig_extradata;
  288. avctx->extradata_size = priv->orig_extradata_size;
  289. priv->orig_extradata = NULL;
  290. priv->orig_extradata_size = 0;
  291. }
  292. if (priv->bsfc) {
  293. av_bsf_free(&priv->bsfc);
  294. }
  295. av_freep(&priv->sps_pps_buf);
  296. av_frame_free (&priv->pic);
  297. if (priv->head) {
  298. OpaqueList *node = priv->head;
  299. while (node) {
  300. OpaqueList *next = node->next;
  301. av_free(node);
  302. node = next;
  303. }
  304. }
  305. return 0;
  306. }
  307. static av_cold int init_bsf(AVCodecContext *avctx, const char *bsf_name)
  308. {
  309. CHDContext *priv = avctx->priv_data;
  310. const AVBitStreamFilter *bsf;
  311. int avret;
  312. void *extradata = NULL;
  313. size_t size = 0;
  314. bsf = av_bsf_get_by_name(bsf_name);
  315. if (!bsf) {
  316. av_log(avctx, AV_LOG_ERROR,
  317. "Cannot open the %s BSF!\n", bsf_name);
  318. return AVERROR_BSF_NOT_FOUND;
  319. }
  320. avret = av_bsf_alloc(bsf, &priv->bsfc);
  321. if (avret != 0) {
  322. return avret;
  323. }
  324. avret = avcodec_parameters_from_context(priv->bsfc->par_in, avctx);
  325. if (avret != 0) {
  326. return avret;
  327. }
  328. avret = av_bsf_init(priv->bsfc);
  329. if (avret != 0) {
  330. return avret;
  331. }
  332. /* Back up the extradata so it can be restored at close time. */
  333. priv->orig_extradata = avctx->extradata;
  334. priv->orig_extradata_size = avctx->extradata_size;
  335. size = priv->bsfc->par_out->extradata_size;
  336. extradata = av_malloc(size + AV_INPUT_BUFFER_PADDING_SIZE);
  337. if (!extradata) {
  338. av_log(avctx, AV_LOG_ERROR,
  339. "Failed to allocate copy of extradata\n");
  340. return AVERROR(ENOMEM);
  341. }
  342. memcpy(extradata, priv->bsfc->par_out->extradata, size);
  343. avctx->extradata = extradata;
  344. avctx->extradata_size = size;
  345. return 0;
  346. }
  347. static av_cold int init(AVCodecContext *avctx)
  348. {
  349. CHDContext* priv;
  350. int avret;
  351. BC_STATUS ret;
  352. BC_INFO_CRYSTAL version;
  353. BC_INPUT_FORMAT format = {
  354. .FGTEnable = FALSE,
  355. .Progressive = TRUE,
  356. .OptFlags = 0x80000000 | vdecFrameRate59_94 | 0x40,
  357. .width = avctx->width,
  358. .height = avctx->height,
  359. };
  360. BC_MEDIA_SUBTYPE subtype;
  361. uint32_t mode = DTS_PLAYBACK_MODE |
  362. DTS_LOAD_FILE_PLAY_FW |
  363. DTS_SKIP_TX_CHK_CPB |
  364. DTS_PLAYBACK_DROP_RPT_MODE |
  365. DTS_SINGLE_THREADED_MODE |
  366. DTS_DFLT_RESOLUTION(vdecRESOLUTION_1080p23_976);
  367. av_log(avctx, AV_LOG_VERBOSE, "CrystalHD Init for %s\n",
  368. avctx->codec->name);
  369. avctx->pix_fmt = AV_PIX_FMT_YUYV422;
  370. /* Initialize the library */
  371. priv = avctx->priv_data;
  372. priv->avctx = avctx;
  373. priv->is_nal = avctx->extradata_size > 0 && *(avctx->extradata) == 1;
  374. priv->pic = av_frame_alloc();
  375. subtype = id2subtype(priv, avctx->codec->id);
  376. switch (subtype) {
  377. case BC_MSUBTYPE_AVC1:
  378. avret = init_bsf(avctx, "h264_mp4toannexb");
  379. if (avret != 0) {
  380. return avret;
  381. }
  382. subtype = BC_MSUBTYPE_H264;
  383. format.startCodeSz = 4;
  384. format.pMetaData = avctx->extradata;
  385. format.metaDataSz = avctx->extradata_size;
  386. break;
  387. case BC_MSUBTYPE_H264:
  388. format.startCodeSz = 4;
  389. // Fall-through
  390. case BC_MSUBTYPE_VC1:
  391. case BC_MSUBTYPE_WVC1:
  392. case BC_MSUBTYPE_WMV3:
  393. case BC_MSUBTYPE_WMVA:
  394. case BC_MSUBTYPE_MPEG2VIDEO:
  395. case BC_MSUBTYPE_DIVX:
  396. case BC_MSUBTYPE_DIVX311:
  397. format.pMetaData = avctx->extradata;
  398. format.metaDataSz = avctx->extradata_size;
  399. break;
  400. default:
  401. av_log(avctx, AV_LOG_ERROR, "CrystalHD: Unknown codec name\n");
  402. return AVERROR(EINVAL);
  403. }
  404. format.mSubtype = subtype;
  405. if (priv->sWidth) {
  406. format.bEnableScaling = 1;
  407. format.ScalingParams.sWidth = priv->sWidth;
  408. }
  409. /* Get a decoder instance */
  410. av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: starting up\n");
  411. // Initialize the Link and Decoder devices
  412. ret = DtsDeviceOpen(&priv->dev, mode);
  413. if (ret != BC_STS_SUCCESS) {
  414. av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: DtsDeviceOpen failed\n");
  415. goto fail;
  416. }
  417. ret = DtsCrystalHDVersion(priv->dev, &version);
  418. if (ret != BC_STS_SUCCESS) {
  419. av_log(avctx, AV_LOG_VERBOSE,
  420. "CrystalHD: DtsCrystalHDVersion failed\n");
  421. goto fail;
  422. }
  423. priv->is_70012 = version.device == 0;
  424. if (priv->is_70012 &&
  425. (subtype == BC_MSUBTYPE_DIVX || subtype == BC_MSUBTYPE_DIVX311)) {
  426. av_log(avctx, AV_LOG_VERBOSE,
  427. "CrystalHD: BCM70012 doesn't support MPEG4-ASP/DivX/Xvid\n");
  428. goto fail;
  429. }
  430. ret = DtsSetInputFormat(priv->dev, &format);
  431. if (ret != BC_STS_SUCCESS) {
  432. av_log(avctx, AV_LOG_ERROR, "CrystalHD: SetInputFormat failed\n");
  433. goto fail;
  434. }
  435. ret = DtsOpenDecoder(priv->dev, BC_STREAM_TYPE_ES);
  436. if (ret != BC_STS_SUCCESS) {
  437. av_log(avctx, AV_LOG_ERROR, "CrystalHD: DtsOpenDecoder failed\n");
  438. goto fail;
  439. }
  440. ret = DtsSetColorSpace(priv->dev, OUTPUT_MODE422_YUY2);
  441. if (ret != BC_STS_SUCCESS) {
  442. av_log(avctx, AV_LOG_ERROR, "CrystalHD: DtsSetColorSpace failed\n");
  443. goto fail;
  444. }
  445. ret = DtsStartDecoder(priv->dev);
  446. if (ret != BC_STS_SUCCESS) {
  447. av_log(avctx, AV_LOG_ERROR, "CrystalHD: DtsStartDecoder failed\n");
  448. goto fail;
  449. }
  450. ret = DtsStartCapture(priv->dev);
  451. if (ret != BC_STS_SUCCESS) {
  452. av_log(avctx, AV_LOG_ERROR, "CrystalHD: DtsStartCapture failed\n");
  453. goto fail;
  454. }
  455. av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: Init complete.\n");
  456. return 0;
  457. fail:
  458. uninit(avctx);
  459. return -1;
  460. }
  461. static inline CopyRet copy_frame(AVCodecContext *avctx,
  462. BC_DTS_PROC_OUT *output,
  463. void *data, int *got_frame)
  464. {
  465. BC_STATUS ret;
  466. BC_DTS_STATUS decoder_status = { 0, };
  467. uint8_t interlaced;
  468. CHDContext *priv = avctx->priv_data;
  469. int64_t pkt_pts = AV_NOPTS_VALUE;
  470. uint8_t bottom_field = (output->PicInfo.flags & VDEC_FLAG_BOTTOMFIELD) ==
  471. VDEC_FLAG_BOTTOMFIELD;
  472. uint8_t bottom_first = !!(output->PicInfo.flags & VDEC_FLAG_BOTTOM_FIRST);
  473. int width = output->PicInfo.width;
  474. int height = output->PicInfo.height;
  475. int bwidth;
  476. uint8_t *src = output->Ybuff;
  477. int sStride;
  478. uint8_t *dst;
  479. int dStride;
  480. if (output->PicInfo.timeStamp != 0) {
  481. OpaqueList *node = opaque_list_pop(priv, output->PicInfo.timeStamp);
  482. if (node) {
  483. pkt_pts = node->reordered_opaque;
  484. av_free(node);
  485. } else {
  486. /*
  487. * We will encounter a situation where a timestamp cannot be
  488. * popped if a second field is being returned. In this case,
  489. * each field has the same timestamp and the first one will
  490. * cause it to be popped. We'll avoid overwriting the valid
  491. * timestamp below.
  492. */
  493. }
  494. av_log(avctx, AV_LOG_VERBOSE, "output \"pts\": %"PRIu64"\n",
  495. output->PicInfo.timeStamp);
  496. }
  497. ret = DtsGetDriverStatus(priv->dev, &decoder_status);
  498. if (ret != BC_STS_SUCCESS) {
  499. av_log(avctx, AV_LOG_ERROR,
  500. "CrystalHD: GetDriverStatus failed: %u\n", ret);
  501. return RET_ERROR;
  502. }
  503. interlaced = output->PicInfo.flags & VDEC_FLAG_INTERLACED_SRC;
  504. av_log(avctx, AV_LOG_VERBOSE, "Interlaced state: %d\n",
  505. interlaced);
  506. if (priv->pic->data[0] && !priv->need_second_field)
  507. av_frame_unref(priv->pic);
  508. priv->need_second_field = interlaced && !priv->need_second_field;
  509. if (!priv->pic->data[0]) {
  510. if (ff_get_buffer(avctx, priv->pic, AV_GET_BUFFER_FLAG_REF) < 0)
  511. return RET_ERROR;
  512. }
  513. bwidth = av_image_get_linesize(avctx->pix_fmt, width, 0);
  514. if (priv->is_70012) {
  515. int pStride;
  516. if (width <= 720)
  517. pStride = 720;
  518. else if (width <= 1280)
  519. pStride = 1280;
  520. else pStride = 1920;
  521. sStride = av_image_get_linesize(avctx->pix_fmt, pStride, 0);
  522. } else {
  523. sStride = bwidth;
  524. }
  525. dStride = priv->pic->linesize[0];
  526. dst = priv->pic->data[0];
  527. av_log(priv->avctx, AV_LOG_VERBOSE, "CrystalHD: Copying out frame\n");
  528. /*
  529. * The hardware doesn't return the first sample of a picture.
  530. * Ignoring why it behaves this way, it's better to copy the sample from
  531. * the second line, rather than the next sample across because the chroma
  532. * values should be correct (assuming the decoded video was 4:2:0, which
  533. * it was).
  534. */
  535. *((uint32_t *)src) = *((uint32_t *)(src + sStride));
  536. if (interlaced) {
  537. int dY = 0;
  538. int sY = 0;
  539. height /= 2;
  540. if (bottom_field) {
  541. av_log(priv->avctx, AV_LOG_VERBOSE, "Interlaced: bottom field\n");
  542. dY = 1;
  543. } else {
  544. av_log(priv->avctx, AV_LOG_VERBOSE, "Interlaced: top field\n");
  545. dY = 0;
  546. }
  547. for (sY = 0; sY < height; dY++, sY++) {
  548. memcpy(&(dst[dY * dStride]), &(src[sY * sStride]), bwidth);
  549. dY++;
  550. }
  551. } else {
  552. av_image_copy_plane(dst, dStride, src, sStride, bwidth, height);
  553. }
  554. priv->pic->interlaced_frame = interlaced;
  555. if (interlaced)
  556. priv->pic->top_field_first = !bottom_first;
  557. if (pkt_pts != AV_NOPTS_VALUE) {
  558. priv->pic->pts = pkt_pts;
  559. #if FF_API_PKT_PTS
  560. FF_DISABLE_DEPRECATION_WARNINGS
  561. priv->pic->pkt_pts = pkt_pts;
  562. FF_ENABLE_DEPRECATION_WARNINGS
  563. #endif
  564. }
  565. av_frame_set_pkt_pos(priv->pic, -1);
  566. av_frame_set_pkt_duration(priv->pic, 0);
  567. av_frame_set_pkt_size(priv->pic, -1);
  568. if (!priv->need_second_field) {
  569. *got_frame = 1;
  570. if ((ret = av_frame_ref(data, priv->pic)) < 0) {
  571. return ret;
  572. }
  573. }
  574. return RET_OK;
  575. }
  576. static inline CopyRet receive_frame(AVCodecContext *avctx,
  577. void *data, int *got_frame)
  578. {
  579. BC_STATUS ret;
  580. BC_DTS_PROC_OUT output = {
  581. .PicInfo.width = avctx->width,
  582. .PicInfo.height = avctx->height,
  583. };
  584. CHDContext *priv = avctx->priv_data;
  585. HANDLE dev = priv->dev;
  586. *got_frame = 0;
  587. // Request decoded data from the driver
  588. ret = DtsProcOutputNoCopy(dev, OUTPUT_PROC_TIMEOUT, &output);
  589. if (ret == BC_STS_FMT_CHANGE) {
  590. av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: Initial format change\n");
  591. avctx->width = output.PicInfo.width;
  592. avctx->height = output.PicInfo.height;
  593. switch ( output.PicInfo.aspect_ratio ) {
  594. case vdecAspectRatioSquare:
  595. avctx->sample_aspect_ratio = (AVRational) { 1, 1};
  596. break;
  597. case vdecAspectRatio12_11:
  598. avctx->sample_aspect_ratio = (AVRational) { 12, 11};
  599. break;
  600. case vdecAspectRatio10_11:
  601. avctx->sample_aspect_ratio = (AVRational) { 10, 11};
  602. break;
  603. case vdecAspectRatio16_11:
  604. avctx->sample_aspect_ratio = (AVRational) { 16, 11};
  605. break;
  606. case vdecAspectRatio40_33:
  607. avctx->sample_aspect_ratio = (AVRational) { 40, 33};
  608. break;
  609. case vdecAspectRatio24_11:
  610. avctx->sample_aspect_ratio = (AVRational) { 24, 11};
  611. break;
  612. case vdecAspectRatio20_11:
  613. avctx->sample_aspect_ratio = (AVRational) { 20, 11};
  614. break;
  615. case vdecAspectRatio32_11:
  616. avctx->sample_aspect_ratio = (AVRational) { 32, 11};
  617. break;
  618. case vdecAspectRatio80_33:
  619. avctx->sample_aspect_ratio = (AVRational) { 80, 33};
  620. break;
  621. case vdecAspectRatio18_11:
  622. avctx->sample_aspect_ratio = (AVRational) { 18, 11};
  623. break;
  624. case vdecAspectRatio15_11:
  625. avctx->sample_aspect_ratio = (AVRational) { 15, 11};
  626. break;
  627. case vdecAspectRatio64_33:
  628. avctx->sample_aspect_ratio = (AVRational) { 64, 33};
  629. break;
  630. case vdecAspectRatio160_99:
  631. avctx->sample_aspect_ratio = (AVRational) {160, 99};
  632. break;
  633. case vdecAspectRatio4_3:
  634. avctx->sample_aspect_ratio = (AVRational) { 4, 3};
  635. break;
  636. case vdecAspectRatio16_9:
  637. avctx->sample_aspect_ratio = (AVRational) { 16, 9};
  638. break;
  639. case vdecAspectRatio221_1:
  640. avctx->sample_aspect_ratio = (AVRational) {221, 1};
  641. break;
  642. }
  643. return RET_OK;
  644. } else if (ret == BC_STS_SUCCESS) {
  645. int copy_ret = -1;
  646. if (output.PoutFlags & BC_POUT_FLAGS_PIB_VALID) {
  647. if (avctx->codec->id == AV_CODEC_ID_MPEG4 &&
  648. output.PicInfo.timeStamp == 0 && priv->bframe_bug) {
  649. if (!priv->bframe_bug) {
  650. av_log(avctx, AV_LOG_VERBOSE,
  651. "CrystalHD: Not returning packed frame twice.\n");
  652. }
  653. DtsReleaseOutputBuffs(dev, NULL, FALSE);
  654. return RET_COPY_AGAIN;
  655. }
  656. print_frame_info(priv, &output);
  657. copy_ret = copy_frame(avctx, &output, data, got_frame);
  658. } else {
  659. /*
  660. * An invalid frame has been consumed.
  661. */
  662. av_log(avctx, AV_LOG_ERROR, "CrystalHD: ProcOutput succeeded with "
  663. "invalid PIB\n");
  664. copy_ret = RET_OK;
  665. }
  666. DtsReleaseOutputBuffs(dev, NULL, FALSE);
  667. return copy_ret;
  668. } else if (ret == BC_STS_BUSY) {
  669. return RET_OK;
  670. } else {
  671. av_log(avctx, AV_LOG_ERROR, "CrystalHD: ProcOutput failed %d\n", ret);
  672. return RET_ERROR;
  673. }
  674. }
  675. static int crystalhd_decode_packet(AVCodecContext *avctx, const AVPacket *avpkt)
  676. {
  677. BC_STATUS bc_ret;
  678. CHDContext *priv = avctx->priv_data;
  679. HANDLE dev = priv->dev;
  680. AVPacket filtered_packet = { 0 };
  681. int ret = 0;
  682. av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: decode_packet\n");
  683. if (avpkt && avpkt->size) {
  684. int32_t tx_free = (int32_t)DtsTxFreeSize(dev);
  685. if (!priv->bframe_bug && (avpkt->size == 6 || avpkt->size == 7)) {
  686. /*
  687. * Drop frames trigger the bug
  688. */
  689. av_log(avctx, AV_LOG_WARNING,
  690. "CrystalHD: Enabling work-around for packed b-frame bug\n");
  691. priv->bframe_bug = 1;
  692. } else if (priv->bframe_bug && avpkt->size == 8) {
  693. /*
  694. * Delay frames don't trigger the bug
  695. */
  696. av_log(avctx, AV_LOG_WARNING,
  697. "CrystalHD: Disabling work-around for packed b-frame bug\n");
  698. priv->bframe_bug = 0;
  699. }
  700. if (priv->bsfc) {
  701. AVPacket filter_packet = { 0 };
  702. ret = av_packet_ref(&filter_packet, avpkt);
  703. if (ret < 0) {
  704. av_log(avctx, AV_LOG_ERROR, "CrystalHD: mpv4toannexb filter "
  705. "failed to ref input packet\n");
  706. goto exit;
  707. }
  708. ret = av_bsf_send_packet(priv->bsfc, &filter_packet);
  709. if (ret < 0) {
  710. av_log(avctx, AV_LOG_ERROR, "CrystalHD: mpv4toannexb filter "
  711. "failed to send input packet\n");
  712. goto exit;
  713. }
  714. ret = av_bsf_receive_packet(priv->bsfc, &filtered_packet);
  715. if (ret < 0) {
  716. av_log(avctx, AV_LOG_ERROR, "CrystalHD: mpv4toannexb filter "
  717. "failed to receive output packet\n");
  718. goto exit;
  719. }
  720. avpkt = &filtered_packet;
  721. av_packet_unref(&filter_packet);
  722. }
  723. if (avpkt->size < tx_free) {
  724. /*
  725. * Despite being notionally opaque, either libcrystalhd or
  726. * the hardware itself will mangle pts values that are too
  727. * small or too large. The docs claim it should be in units
  728. * of 100ns. Given that we're nominally dealing with a black
  729. * box on both sides, any transform we do has no guarantee of
  730. * avoiding mangling so we need to build a mapping to values
  731. * we know will not be mangled.
  732. */
  733. int64_t safe_pts = avpkt->pts == AV_NOPTS_VALUE ? 0 : avpkt->pts;
  734. uint64_t pts = opaque_list_push(priv, safe_pts);
  735. if (!pts) {
  736. ret = AVERROR(ENOMEM);
  737. goto exit;
  738. }
  739. av_log(priv->avctx, AV_LOG_VERBOSE,
  740. "input \"pts\": %"PRIu64"\n", pts);
  741. bc_ret = DtsProcInput(dev, avpkt->data, avpkt->size, pts, 0);
  742. if (bc_ret == BC_STS_BUSY) {
  743. av_log(avctx, AV_LOG_WARNING,
  744. "CrystalHD: ProcInput returned busy\n");
  745. ret = AVERROR(EAGAIN);
  746. goto exit;
  747. } else if (bc_ret != BC_STS_SUCCESS) {
  748. av_log(avctx, AV_LOG_ERROR,
  749. "CrystalHD: ProcInput failed: %u\n", ret);
  750. ret = -1;
  751. goto exit;
  752. }
  753. } else {
  754. av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: Input buffer full\n");
  755. ret = AVERROR(EAGAIN);
  756. goto exit;
  757. }
  758. } else {
  759. av_log(avctx, AV_LOG_INFO, "CrystalHD: No more input data\n");
  760. ret = AVERROR_EOF;
  761. goto exit;
  762. }
  763. exit:
  764. av_packet_unref(&filtered_packet);
  765. return ret;
  766. }
  767. static int crystalhd_receive_frame(AVCodecContext *avctx, AVFrame *frame)
  768. {
  769. BC_STATUS bc_ret;
  770. BC_DTS_STATUS decoder_status = { 0, };
  771. CopyRet rec_ret;
  772. CHDContext *priv = avctx->priv_data;
  773. HANDLE dev = priv->dev;
  774. int got_frame = 0;
  775. av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: receive_frame\n");
  776. bc_ret = DtsGetDriverStatus(dev, &decoder_status);
  777. if (bc_ret != BC_STS_SUCCESS) {
  778. av_log(avctx, AV_LOG_ERROR, "CrystalHD: GetDriverStatus failed\n");
  779. return -1;
  780. }
  781. if (decoder_status.ReadyListCount == 0) {
  782. av_log(avctx, AV_LOG_INFO, "CrystalHD: Insufficient frames ready. Returning\n");
  783. return AVERROR(EAGAIN);
  784. }
  785. rec_ret = receive_frame(avctx, frame, &got_frame);
  786. if (rec_ret == RET_ERROR) {
  787. return -1;
  788. } else if (got_frame == 0) {
  789. return AVERROR(EAGAIN);
  790. } else {
  791. return 0;
  792. }
  793. }
  794. #define DEFINE_CRYSTALHD_DECODER(x, X) \
  795. static const AVClass x##_crystalhd_class = { \
  796. .class_name = #x "_crystalhd", \
  797. .item_name = av_default_item_name, \
  798. .option = options, \
  799. .version = LIBAVUTIL_VERSION_INT, \
  800. }; \
  801. AVCodec ff_##x##_crystalhd_decoder = { \
  802. .name = #x "_crystalhd", \
  803. .long_name = NULL_IF_CONFIG_SMALL("CrystalHD " #X " decoder"), \
  804. .type = AVMEDIA_TYPE_VIDEO, \
  805. .id = AV_CODEC_ID_##X, \
  806. .priv_data_size = sizeof(CHDContext), \
  807. .priv_class = &x##_crystalhd_class, \
  808. .init = init, \
  809. .close = uninit, \
  810. .send_packet = crystalhd_decode_packet, \
  811. .receive_frame = crystalhd_receive_frame, \
  812. .flush = flush, \
  813. .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING, \
  814. .pix_fmts = (const enum AVPixelFormat[]){AV_PIX_FMT_YUYV422, AV_PIX_FMT_NONE}, \
  815. };
  816. #if CONFIG_H264_CRYSTALHD_DECODER
  817. DEFINE_CRYSTALHD_DECODER(h264, H264)
  818. #endif
  819. #if CONFIG_MPEG2_CRYSTALHD_DECODER
  820. DEFINE_CRYSTALHD_DECODER(mpeg2, MPEG2VIDEO)
  821. #endif
  822. #if CONFIG_MPEG4_CRYSTALHD_DECODER
  823. DEFINE_CRYSTALHD_DECODER(mpeg4, MPEG4)
  824. #endif
  825. #if CONFIG_MSMPEG4_CRYSTALHD_DECODER
  826. DEFINE_CRYSTALHD_DECODER(msmpeg4, MSMPEG4V3)
  827. #endif
  828. #if CONFIG_VC1_CRYSTALHD_DECODER
  829. DEFINE_CRYSTALHD_DECODER(vc1, VC1)
  830. #endif
  831. #if CONFIG_WMV3_CRYSTALHD_DECODER
  832. DEFINE_CRYSTALHD_DECODER(wmv3, WMV3)
  833. #endif