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