Commit a07c07e7 authored by Philip Langdale's avatar Philip Langdale

crystalhd: Simplify output frame handling

The old code had to retain a partial frame across two calls in
the case of separate interlaced fields. Now, we know that we'll
get both fields within the same receive_frame call, and so we
don't need to manage the frame as private state any more.
parent 3019b4f6
...@@ -117,7 +117,6 @@ typedef struct OpaqueList { ...@@ -117,7 +117,6 @@ typedef struct OpaqueList {
typedef struct { typedef struct {
AVClass *av_class; AVClass *av_class;
AVCodecContext *avctx; AVCodecContext *avctx;
AVFrame *pic;
HANDLE dev; HANDLE dev;
uint8_t *orig_extradata; uint8_t *orig_extradata;
...@@ -308,8 +307,6 @@ static void flush(AVCodecContext *avctx) ...@@ -308,8 +307,6 @@ static void flush(AVCodecContext *avctx)
priv->need_second_field = 0; priv->need_second_field = 0;
priv->draining = 0; priv->draining = 0;
av_frame_unref (priv->pic);
/* Flush mode 4 flushes all software and hardware buffers. */ /* Flush mode 4 flushes all software and hardware buffers. */
DtsFlushInput(priv->dev, 4); DtsFlushInput(priv->dev, 4);
} }
...@@ -344,8 +341,6 @@ static av_cold int uninit(AVCodecContext *avctx) ...@@ -344,8 +341,6 @@ static av_cold int uninit(AVCodecContext *avctx)
av_freep(&priv->sps_pps_buf); av_freep(&priv->sps_pps_buf);
av_frame_free (&priv->pic);
if (priv->head) { if (priv->head) {
OpaqueList *node = priv->head; OpaqueList *node = priv->head;
while (node) { while (node) {
...@@ -440,7 +435,6 @@ static av_cold int init(AVCodecContext *avctx) ...@@ -440,7 +435,6 @@ static av_cold int init(AVCodecContext *avctx)
priv = avctx->priv_data; priv = avctx->priv_data;
priv->avctx = avctx; priv->avctx = avctx;
priv->is_nal = avctx->extradata_size > 0 && *(avctx->extradata) == 1; priv->is_nal = avctx->extradata_size > 0 && *(avctx->extradata) == 1;
priv->pic = av_frame_alloc();
priv->draining = 0; priv->draining = 0;
subtype = id2subtype(priv, avctx->codec->id); subtype = id2subtype(priv, avctx->codec->id);
...@@ -543,7 +537,7 @@ static av_cold int init(AVCodecContext *avctx) ...@@ -543,7 +537,7 @@ static av_cold int init(AVCodecContext *avctx)
static inline CopyRet copy_frame(AVCodecContext *avctx, static inline CopyRet copy_frame(AVCodecContext *avctx,
BC_DTS_PROC_OUT *output, BC_DTS_PROC_OUT *output,
void *data, int *got_frame) AVFrame *frame, int *got_frame)
{ {
BC_STATUS ret; BC_STATUS ret;
BC_DTS_STATUS decoder_status = { 0, }; BC_DTS_STATUS decoder_status = { 0, };
...@@ -594,13 +588,10 @@ static inline CopyRet copy_frame(AVCodecContext *avctx, ...@@ -594,13 +588,10 @@ static inline CopyRet copy_frame(AVCodecContext *avctx,
av_log(avctx, AV_LOG_VERBOSE, "Interlaced state: %d\n", av_log(avctx, AV_LOG_VERBOSE, "Interlaced state: %d\n",
interlaced); interlaced);
if (priv->pic->data[0] && !priv->need_second_field)
av_frame_unref(priv->pic);
priv->need_second_field = interlaced && !priv->need_second_field; priv->need_second_field = interlaced && !priv->need_second_field;
if (!priv->pic->data[0]) { if (!frame->data[0]) {
if (ff_get_buffer(avctx, priv->pic, AV_GET_BUFFER_FLAG_REF) < 0) if (ff_get_buffer(avctx, frame, 0) < 0)
return RET_ERROR; return RET_ERROR;
} }
...@@ -618,8 +609,8 @@ static inline CopyRet copy_frame(AVCodecContext *avctx, ...@@ -618,8 +609,8 @@ static inline CopyRet copy_frame(AVCodecContext *avctx,
sStride = bwidth; sStride = bwidth;
} }
dStride = priv->pic->linesize[0]; dStride = frame->linesize[0];
dst = priv->pic->data[0]; dst = frame->data[0];
av_log(priv->avctx, AV_LOG_VERBOSE, "CrystalHD: Copying out frame\n"); av_log(priv->avctx, AV_LOG_VERBOSE, "CrystalHD: Copying out frame\n");
...@@ -653,27 +644,24 @@ static inline CopyRet copy_frame(AVCodecContext *avctx, ...@@ -653,27 +644,24 @@ static inline CopyRet copy_frame(AVCodecContext *avctx,
av_image_copy_plane(dst, dStride, src, sStride, bwidth, height); av_image_copy_plane(dst, dStride, src, sStride, bwidth, height);
} }
priv->pic->interlaced_frame = interlaced; frame->interlaced_frame = interlaced;
if (interlaced) if (interlaced)
priv->pic->top_field_first = !bottom_first; frame->top_field_first = !bottom_first;
if (pkt_pts != AV_NOPTS_VALUE) { if (pkt_pts != AV_NOPTS_VALUE) {
priv->pic->pts = pkt_pts; frame->pts = pkt_pts;
#if FF_API_PKT_PTS #if FF_API_PKT_PTS
FF_DISABLE_DEPRECATION_WARNINGS FF_DISABLE_DEPRECATION_WARNINGS
priv->pic->pkt_pts = pkt_pts; frame->pkt_pts = pkt_pts;
FF_ENABLE_DEPRECATION_WARNINGS FF_ENABLE_DEPRECATION_WARNINGS
#endif #endif
} }
av_frame_set_pkt_pos(priv->pic, -1); av_frame_set_pkt_pos(frame, -1);
av_frame_set_pkt_duration(priv->pic, 0); av_frame_set_pkt_duration(frame, 0);
av_frame_set_pkt_size(priv->pic, -1); av_frame_set_pkt_size(frame, -1);
if (!priv->need_second_field) { if (!priv->need_second_field) {
*got_frame = 1; *got_frame = 1;
if ((ret = av_frame_ref(data, priv->pic)) < 0) {
return ret;
}
} else { } else {
return RET_COPY_AGAIN; return RET_COPY_AGAIN;
} }
...@@ -683,7 +671,7 @@ FF_ENABLE_DEPRECATION_WARNINGS ...@@ -683,7 +671,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
static inline CopyRet receive_frame(AVCodecContext *avctx, static inline CopyRet receive_frame(AVCodecContext *avctx,
void *data, int *got_frame) AVFrame *frame, int *got_frame)
{ {
BC_STATUS ret; BC_STATUS ret;
BC_DTS_PROC_OUT output = { BC_DTS_PROC_OUT output = {
...@@ -767,7 +755,7 @@ static inline CopyRet receive_frame(AVCodecContext *avctx, ...@@ -767,7 +755,7 @@ static inline CopyRet receive_frame(AVCodecContext *avctx,
print_frame_info(priv, &output); print_frame_info(priv, &output);
copy_ret = copy_frame(avctx, &output, data, got_frame); copy_ret = copy_frame(avctx, &output, frame, got_frame);
} else { } else {
/* /*
* An invalid frame has been consumed. * An invalid frame has been consumed.
...@@ -945,7 +933,7 @@ static int crystalhd_receive_frame(AVCodecContext *avctx, AVFrame *frame) ...@@ -945,7 +933,7 @@ static int crystalhd_receive_frame(AVCodecContext *avctx, AVFrame *frame)
.send_packet = crystalhd_decode_packet, \ .send_packet = crystalhd_decode_packet, \
.receive_frame = crystalhd_receive_frame, \ .receive_frame = crystalhd_receive_frame, \
.flush = flush, \ .flush = flush, \
.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING, \ .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING, \
.pix_fmts = (const enum AVPixelFormat[]){AV_PIX_FMT_YUYV422, AV_PIX_FMT_NONE}, \ .pix_fmts = (const enum AVPixelFormat[]){AV_PIX_FMT_YUYV422, AV_PIX_FMT_NONE}, \
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment