Skip to content
Snippets Groups Projects
Commit dd0c789b authored by Bobby Bingham's avatar Bobby Bingham
Browse files

Hook decoder up to libavfilter's direct rendering for ffplay

Originally committed as revision 22754 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent 0fb49b59
No related branches found
No related tags found
No related merge requests found
......@@ -1558,14 +1558,71 @@ static int get_video_frame(VideoState *is, AVFrame *frame, int64_t *pts, AVPacke
typedef struct {
VideoState *is;
AVFrame *frame;
int use_dr1;
} FilterPriv;
static int input_get_buffer(AVCodecContext *codec, AVFrame *pic)
{
AVFilterContext *ctx = codec->opaque;
AVFilterPicRef *ref;
int perms = AV_PERM_WRITE;
int w, h, stride[4];
unsigned edge;
if(pic->buffer_hints & FF_BUFFER_HINTS_VALID) {
if(pic->buffer_hints & FF_BUFFER_HINTS_READABLE) perms |= AV_PERM_READ;
if(pic->buffer_hints & FF_BUFFER_HINTS_PRESERVE) perms |= AV_PERM_PRESERVE;
if(pic->buffer_hints & FF_BUFFER_HINTS_REUSABLE) perms |= AV_PERM_REUSE2;
}
if(pic->reference) perms |= AV_PERM_READ | AV_PERM_PRESERVE;
w = codec->width;
h = codec->height;
avcodec_align_dimensions2(codec, &w, &h, stride);
edge = codec->flags & CODEC_FLAG_EMU_EDGE ? 0 : avcodec_get_edge_width();
w += edge << 1;
h += edge << 1;
if(!(ref = avfilter_get_video_buffer(ctx->outputs[0], perms, w, h)))
return -1;
ref->w = codec->width;
ref->h = codec->height;
for(int i = 0; i < 3; i ++) {
unsigned hshift = i == 0 ? 0 : av_pix_fmt_descriptors[ref->pic->format].log2_chroma_w;
unsigned vshift = i == 0 ? 0 : av_pix_fmt_descriptors[ref->pic->format].log2_chroma_h;
ref->data[i] += (edge >> hshift) + ((edge * ref->linesize[i]) >> vshift);
pic->data[i] = ref->data[i];
pic->linesize[i] = ref->linesize[i];
}
pic->opaque = ref;
pic->age = INT_MAX;
pic->type = FF_BUFFER_TYPE_USER;
return 0;
}
static void input_release_buffer(AVCodecContext *codec, AVFrame *pic)
{
memset(pic->data, 0, sizeof(pic->data));
avfilter_unref_pic(pic->opaque);
}
static int input_init(AVFilterContext *ctx, const char *args, void *opaque)
{
FilterPriv *priv = ctx->priv;
AVCodecContext *codec;
if(!opaque) return -1;
priv->is = opaque;
codec = priv->is->video_st->codec;
codec->opaque = ctx;
if(codec->codec->capabilities & CODEC_CAP_DR1) {
priv->use_dr1 = 1;
codec->get_buffer = input_get_buffer;
codec->release_buffer = input_release_buffer;
}
priv->frame = avcodec_alloc_frame();
return 0;
......@@ -1590,11 +1647,13 @@ static int input_request_frame(AVFilterLink *link)
if (ret < 0)
return -1;
/* FIXME: until I figure out how to hook everything up to the codec
* right, we're just copying the entire frame. */
if(priv->use_dr1) {
picref = priv->frame->opaque;
} else {
picref = avfilter_get_video_buffer(link, AV_PERM_WRITE, link->w, link->h);
av_picture_copy((AVPicture *)&picref->data, (AVPicture *)priv->frame,
picref->pic->format, link->w, link->h);
}
av_free_packet(&pkt);
picref->pts = pts;
......@@ -1603,6 +1662,7 @@ static int input_request_frame(AVFilterLink *link)
avfilter_start_frame(link, avfilter_ref_pic(picref, ~0));
avfilter_draw_slice(link, 0, link->h, 1);
avfilter_end_frame(link);
if(!priv->use_dr1)
avfilter_unref_pic(picref);
return 0;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment