Define a new struct AVFilterBufferRefVideoProps and add a type field
to AVFilterBufferRef.
Video specific properties in AVFilterBufferRefVideoProps are now
referred to by *video pointer in AVFilterBufferRef.
Patch by S.N. Hemanth Meenakshisundaram smeenaks->ucsd.edu.
Originally committed as revision 24763 to svn://svn.ffmpeg.org/ffmpeg/trunk
| ... | ... |
@@ -377,8 +377,8 @@ static int get_filtered_video_pic(AVFilterContext *ctx, |
| 377 | 377 |
|
| 378 | 378 |
memcpy(pic2->data, pic->data, sizeof(pic->data)); |
| 379 | 379 |
memcpy(pic2->linesize, pic->linesize, sizeof(pic->linesize)); |
| 380 |
- pic2->interlaced_frame = pic->interlaced; |
|
| 381 |
- pic2->top_field_first = pic->top_field_first; |
|
| 380 |
+ pic2->interlaced_frame = pic->video->interlaced; |
|
| 381 |
+ pic2->top_field_first = pic->video->top_field_first; |
|
| 382 | 382 |
|
| 383 | 383 |
return 1; |
| 384 | 384 |
} |
| ... | ... |
@@ -1701,7 +1701,8 @@ static int output_packet(AVInputStream *ist, int ist_index, |
| 1701 | 1701 |
break; |
| 1702 | 1702 |
case AVMEDIA_TYPE_VIDEO: |
| 1703 | 1703 |
#if CONFIG_AVFILTER |
| 1704 |
- ost->st->codec->sample_aspect_ratio = ist->picref->pixel_aspect; |
|
| 1704 |
+ if (ist->picref->video) |
|
| 1705 |
+ ost->st->codec->sample_aspect_ratio = ist->picref->video->pixel_aspect; |
|
| 1705 | 1706 |
#endif |
| 1706 | 1707 |
do_video_out(os, ost, ist, &picture, &frame_size); |
| 1707 | 1708 |
if (vstats_filename && frame_size) |
| ... | ... |
@@ -694,10 +694,10 @@ static void video_image_display(VideoState *is) |
| 694 | 694 |
vp = &is->pictq[is->pictq_rindex]; |
| 695 | 695 |
if (vp->bmp) {
|
| 696 | 696 |
#if CONFIG_AVFILTER |
| 697 |
- if (vp->picref->pixel_aspect.num == 0) |
|
| 697 |
+ if (vp->picref->video->pixel_aspect.num == 0) |
|
| 698 | 698 |
aspect_ratio = 0; |
| 699 | 699 |
else |
| 700 |
- aspect_ratio = av_q2d(vp->picref->pixel_aspect); |
|
| 700 |
+ aspect_ratio = av_q2d(vp->picref->video->pixel_aspect); |
|
| 701 | 701 |
#else |
| 702 | 702 |
|
| 703 | 703 |
/* XXX: use variable in the frame */ |
| ... | ... |
@@ -1582,8 +1582,8 @@ static int input_get_buffer(AVCodecContext *codec, AVFrame *pic) |
| 1582 | 1582 |
if(!(ref = avfilter_get_video_buffer(ctx->outputs[0], perms, w, h))) |
| 1583 | 1583 |
return -1; |
| 1584 | 1584 |
|
| 1585 |
- ref->w = codec->width; |
|
| 1586 |
- ref->h = codec->height; |
|
| 1585 |
+ ref->video->w = codec->width; |
|
| 1586 |
+ ref->video->h = codec->height; |
|
| 1587 | 1587 |
for(i = 0; i < 4; i ++) {
|
| 1588 | 1588 |
unsigned hshift = (i == 1 || i == 2) ? av_pix_fmt_descriptors[ref->format].log2_chroma_w : 0; |
| 1589 | 1589 |
unsigned vshift = (i == 1 || i == 2) ? av_pix_fmt_descriptors[ref->format].log2_chroma_h : 0; |
| ... | ... |
@@ -1616,7 +1616,7 @@ static int input_reget_buffer(AVCodecContext *codec, AVFrame *pic) |
| 1616 | 1616 |
return codec->get_buffer(codec, pic); |
| 1617 | 1617 |
} |
| 1618 | 1618 |
|
| 1619 |
- if ((codec->width != ref->w) || (codec->height != ref->h) || |
|
| 1619 |
+ if ((codec->width != ref->video->w) || (codec->height != ref->video->h) || |
|
| 1620 | 1620 |
(codec->pix_fmt != ref->format)) {
|
| 1621 | 1621 |
av_log(codec, AV_LOG_ERROR, "Picture properties changed.\n"); |
| 1622 | 1622 |
return -1; |
| ... | ... |
@@ -1677,7 +1677,7 @@ static int input_request_frame(AVFilterLink *link) |
| 1677 | 1677 |
|
| 1678 | 1678 |
picref->pts = pts; |
| 1679 | 1679 |
picref->pos = pkt.pos; |
| 1680 |
- picref->pixel_aspect = priv->is->video_st->codec->sample_aspect_ratio; |
|
| 1680 |
+ picref->video->pixel_aspect = priv->is->video_st->codec->sample_aspect_ratio; |
|
| 1681 | 1681 |
avfilter_start_frame(link, picref); |
| 1682 | 1682 |
avfilter_draw_slice(link, 0, link->h, 1); |
| 1683 | 1683 |
avfilter_end_frame(link); |
| ... | ... |
@@ -49,6 +49,10 @@ AVFilterBufferRef *avfilter_ref_buffer(AVFilterBufferRef *ref, int pmask) |
| 49 | 49 |
{
|
| 50 | 50 |
AVFilterBufferRef *ret = av_malloc(sizeof(AVFilterBufferRef)); |
| 51 | 51 |
*ret = *ref; |
| 52 |
+ if (ref->type == AVMEDIA_TYPE_VIDEO) {
|
|
| 53 |
+ ret->video = av_malloc(sizeof(AVFilterBufferRefVideoProps)); |
|
| 54 |
+ *ret->video = *ref->video; |
|
| 55 |
+ } |
|
| 52 | 56 |
ret->perms &= pmask; |
| 53 | 57 |
ret->buf->refcount ++; |
| 54 | 58 |
return ret; |
| ... | ... |
@@ -58,6 +62,7 @@ void avfilter_unref_buffer(AVFilterBufferRef *ref) |
| 58 | 58 |
{
|
| 59 | 59 |
if(!(--ref->buf->refcount)) |
| 60 | 60 |
ref->buf->free(ref->buf); |
| 61 |
+ av_free(ref->video); |
|
| 61 | 62 |
av_free(ref); |
| 62 | 63 |
} |
| 63 | 64 |
|
| ... | ... |
@@ -179,7 +184,7 @@ void ff_dprintf_picref(void *ctx, AVFilterBufferRef *picref, int end) |
| 179 | 179 |
picref->data [0], picref->data [1], picref->data [2], picref->data [3], |
| 180 | 180 |
picref->linesize[0], picref->linesize[1], picref->linesize[2], picref->linesize[3], |
| 181 | 181 |
picref->pts, picref->pos, |
| 182 |
- picref->pixel_aspect.num, picref->pixel_aspect.den, picref->w, picref->h, |
|
| 182 |
+ picref->video->pixel_aspect.num, picref->video->pixel_aspect.den, picref->video->w, picref->video->h, |
|
| 183 | 183 |
end ? "\n" : ""); |
| 184 | 184 |
} |
| 185 | 185 |
|
| ... | ... |
@@ -314,7 +319,7 @@ void avfilter_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) |
| 314 | 314 |
|
| 315 | 315 |
for(i = 0; i < 4; i ++) {
|
| 316 | 316 |
int planew = |
| 317 |
- ff_get_plane_bytewidth(link->format, link->cur_buf->w, i); |
|
| 317 |
+ ff_get_plane_bytewidth(link->format, link->cur_buf->video->w, i); |
|
| 318 | 318 |
|
| 319 | 319 |
if(!src[i]) continue; |
| 320 | 320 |
|
| ... | ... |
@@ -25,7 +25,7 @@ |
| 25 | 25 |
#include "libavutil/avutil.h" |
| 26 | 26 |
|
| 27 | 27 |
#define LIBAVFILTER_VERSION_MAJOR 1 |
| 28 |
-#define LIBAVFILTER_VERSION_MINOR 31 |
|
| 28 |
+#define LIBAVFILTER_VERSION_MINOR 32 |
|
| 29 | 29 |
#define LIBAVFILTER_VERSION_MICRO 0 |
| 30 | 30 |
|
| 31 | 31 |
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ |
| ... | ... |
@@ -89,6 +89,20 @@ typedef struct AVFilterBuffer |
| 89 | 89 |
#define AV_PERM_REUSE2 0x10 ///< can output the buffer multiple times, modified each time |
| 90 | 90 |
|
| 91 | 91 |
/** |
| 92 |
+ * Video specific properties in a reference to an AVFilterBuffer. Since |
|
| 93 |
+ * AVFilterBufferRef is common to different media formats, video specific |
|
| 94 |
+ * per reference properties must be separated out. |
|
| 95 |
+ */ |
|
| 96 |
+typedef struct AVFilterBufferRefVideoProps |
|
| 97 |
+{
|
|
| 98 |
+ int w; ///< image width |
|
| 99 |
+ int h; ///< image height |
|
| 100 |
+ AVRational pixel_aspect; ///< pixel aspect ratio |
|
| 101 |
+ int interlaced; ///< is frame interlaced |
|
| 102 |
+ int top_field_first; ///< field order |
|
| 103 |
+} AVFilterBufferRefVideoProps; |
|
| 104 |
+ |
|
| 105 |
+/** |
|
| 92 | 106 |
* A reference to an AVFilterBuffer. Since filters can manipulate the origin of |
| 93 | 107 |
* a buffer to, for example, crop image without any memcpy, the buffer origin |
| 94 | 108 |
* and dimensions are per-reference properties. Linesize is also useful for |
| ... | ... |
@@ -101,19 +115,15 @@ typedef struct AVFilterBufferRef |
| 101 | 101 |
AVFilterBuffer *buf; ///< the buffer that this is a reference to |
| 102 | 102 |
uint8_t *data[4]; ///< picture data for each plane |
| 103 | 103 |
int linesize[4]; ///< number of bytes per line |
| 104 |
- int w; ///< image width |
|
| 105 |
- int h; ///< image height |
|
| 106 | 104 |
int format; ///< media format |
| 107 | 105 |
|
| 108 | 106 |
int64_t pts; ///< presentation timestamp in units of 1/AV_TIME_BASE |
| 109 | 107 |
int64_t pos; ///< byte position in stream, -1 if unknown |
| 110 | 108 |
|
| 111 |
- AVRational pixel_aspect; ///< pixel aspect ratio |
|
| 112 |
- |
|
| 113 | 109 |
int perms; ///< permissions, see the AV_PERM_* flags |
| 114 | 110 |
|
| 115 |
- int interlaced; ///< is frame interlaced |
|
| 116 |
- int top_field_first; |
|
| 111 |
+ enum AVMediaType type; ///< media type of buffer data |
|
| 112 |
+ AVFilterBufferRefVideoProps *video; ///< video buffer specific properties |
|
| 117 | 113 |
} AVFilterBufferRef; |
| 118 | 114 |
|
| 119 | 115 |
/** |
| ... | ... |
@@ -122,13 +132,13 @@ typedef struct AVFilterBufferRef |
| 122 | 122 |
*/ |
| 123 | 123 |
static inline void avfilter_copy_buffer_ref_props(AVFilterBufferRef *dst, AVFilterBufferRef *src) |
| 124 | 124 |
{
|
| 125 |
+ // copy common properties |
|
| 125 | 126 |
dst->pts = src->pts; |
| 126 | 127 |
dst->pos = src->pos; |
| 127 |
- dst->pixel_aspect = src->pixel_aspect; |
|
| 128 |
- dst->interlaced = src->interlaced; |
|
| 129 |
- dst->top_field_first = src->top_field_first; |
|
| 130 |
- dst->w = src->w; |
|
| 131 |
- dst->h = src->h; |
|
| 128 |
+ |
|
| 129 |
+ switch (src->type) {
|
|
| 130 |
+ case AVMEDIA_TYPE_VIDEO: *dst->video = *src->video; break; |
|
| 131 |
+ } |
|
| 132 | 132 |
} |
| 133 | 133 |
|
| 134 | 134 |
/** |
| ... | ... |
@@ -39,9 +39,10 @@ AVFilterBufferRef *avfilter_default_get_video_buffer(AVFilterLink *link, int per |
| 39 | 39 |
int i, tempsize; |
| 40 | 40 |
char *buf; |
| 41 | 41 |
|
| 42 |
- ref->buf = pic; |
|
| 43 |
- ref->w = w; |
|
| 44 |
- ref->h = h; |
|
| 42 |
+ ref->buf = pic; |
|
| 43 |
+ ref->video = av_mallocz(sizeof(AVFilterBufferRefVideoProps)); |
|
| 44 |
+ ref->video->w = w; |
|
| 45 |
+ ref->video->h = h; |
|
| 45 | 46 |
|
| 46 | 47 |
/* make sure the buffer gets read permission or it's useless for output */ |
| 47 | 48 |
ref->perms = perms | AV_PERM_READ; |
| ... | ... |
@@ -49,15 +50,15 @@ AVFilterBufferRef *avfilter_default_get_video_buffer(AVFilterLink *link, int per |
| 49 | 49 |
pic->refcount = 1; |
| 50 | 50 |
ref->format = link->format; |
| 51 | 51 |
pic->free = avfilter_default_free_buffer; |
| 52 |
- av_fill_image_linesizes(pic->linesize, ref->format, ref->w); |
|
| 52 |
+ av_fill_image_linesizes(pic->linesize, ref->format, ref->video->w); |
|
| 53 | 53 |
|
| 54 | 54 |
for (i=0; i<4;i++) |
| 55 | 55 |
pic->linesize[i] = FFALIGN(pic->linesize[i], 16); |
| 56 | 56 |
|
| 57 |
- tempsize = av_fill_image_pointers(pic->data, ref->format, ref->h, NULL, pic->linesize); |
|
| 57 |
+ tempsize = av_fill_image_pointers(pic->data, ref->format, ref->video->h, NULL, pic->linesize); |
|
| 58 | 58 |
buf = av_malloc(tempsize + 16); // +2 is needed for swscaler, +16 to be |
| 59 | 59 |
// SIMD-friendly |
| 60 |
- av_fill_image_pointers(pic->data, ref->format, ref->h, buf, pic->linesize); |
|
| 60 |
+ av_fill_image_pointers(pic->data, ref->format, ref->video->h, buf, pic->linesize); |
|
| 61 | 61 |
|
| 62 | 62 |
memcpy(ref->data, pic->data, 4*sizeof(pic->data[0])); |
| 63 | 63 |
memcpy(ref->linesize, pic->linesize, 4*sizeof(pic->linesize[0])); |
| ... | ... |
@@ -60,7 +60,7 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) |
| 60 | 60 |
{
|
| 61 | 61 |
AspectContext *aspect = link->dst->priv; |
| 62 | 62 |
|
| 63 |
- picref->pixel_aspect = aspect->aspect; |
|
| 63 |
+ picref->video->pixel_aspect = aspect->aspect; |
|
| 64 | 64 |
avfilter_start_frame(link->dst->outputs[0], picref); |
| 65 | 65 |
} |
| 66 | 66 |
|
| ... | ... |
@@ -135,8 +135,8 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) |
| 135 | 135 |
AVFilterBufferRef *ref2 = avfilter_ref_buffer(picref, ~0); |
| 136 | 136 |
int i; |
| 137 | 137 |
|
| 138 |
- ref2->w = crop->w; |
|
| 139 |
- ref2->h = crop->h; |
|
| 138 |
+ picref->video->w = crop->w; |
|
| 139 |
+ picref->video->h = crop->h; |
|
| 140 | 140 |
|
| 141 | 141 |
ref2->data[0] += crop->y * ref2->linesize[0]; |
| 142 | 142 |
ref2->data[0] += (crop->x * crop->max_step[0]); |
| ... | ... |
@@ -428,9 +428,9 @@ static int color_request_frame(AVFilterLink *link) |
| 428 | 428 |
{
|
| 429 | 429 |
ColorContext *color = link->src->priv; |
| 430 | 430 |
AVFilterBufferRef *picref = avfilter_get_video_buffer(link, AV_PERM_WRITE, color->w, color->h); |
| 431 |
- picref->pixel_aspect = (AVRational) {1, 1};
|
|
| 432 |
- picref->pts = av_rescale_q(color->pts++, color->time_base, AV_TIME_BASE_Q); |
|
| 433 |
- picref->pos = 0; |
|
| 431 |
+ picref->video->pixel_aspect = (AVRational) {1, 1};
|
|
| 432 |
+ picref->pts = av_rescale_q(color->pts++, color->time_base, AV_TIME_BASE_Q); |
|
| 433 |
+ picref->pos = 0; |
|
| 434 | 434 |
|
| 435 | 435 |
avfilter_start_frame(link, avfilter_ref_buffer(picref, ~0)); |
| 436 | 436 |
draw_rectangle(picref, |
| ... | ... |
@@ -156,9 +156,9 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) |
| 156 | 156 |
|
| 157 | 157 |
outlink->out_buf = outpicref; |
| 158 | 158 |
|
| 159 |
- av_reduce(&outpicref->pixel_aspect.num, &outpicref->pixel_aspect.den, |
|
| 160 |
- (int64_t)picref->pixel_aspect.num * outlink->h * link->w, |
|
| 161 |
- (int64_t)picref->pixel_aspect.den * outlink->w * link->h, |
|
| 159 |
+ av_reduce(&outpicref->video->pixel_aspect.num, &outpicref->video->pixel_aspect.den, |
|
| 160 |
+ (int64_t)picref->video->pixel_aspect.num * outlink->h * link->w, |
|
| 161 |
+ (int64_t)picref->video->pixel_aspect.den * outlink->w * link->h, |
|
| 162 | 162 |
INT_MAX); |
| 163 | 163 |
|
| 164 | 164 |
scale->slice_y = 0; |
| ... | ... |
@@ -122,10 +122,10 @@ static int request_frame(AVFilterLink *link) |
| 122 | 122 |
av_picture_copy((AVPicture *)&picref->data, (AVPicture *)&c->frame, |
| 123 | 123 |
picref->format, link->w, link->h); |
| 124 | 124 |
|
| 125 |
- picref->pts = c->pts; |
|
| 126 |
- picref->pixel_aspect = c->pixel_aspect; |
|
| 127 |
- picref->interlaced = c->frame.interlaced_frame; |
|
| 128 |
- picref->top_field_first = c->frame.top_field_first; |
|
| 125 |
+ picref->pts = c->pts; |
|
| 126 |
+ picref->video->pixel_aspect = c->pixel_aspect; |
|
| 127 |
+ picref->video->interlaced = c->frame.interlaced_frame; |
|
| 128 |
+ picref->video->top_field_first = c->frame.top_field_first; |
|
| 129 | 129 |
avfilter_start_frame(link, avfilter_ref_buffer(picref, ~0)); |
| 130 | 130 |
avfilter_draw_slice(link, 0, link->h, 1); |
| 131 | 131 |
avfilter_end_frame(link); |