unsigned int crop_height;
bool selection_set;
struct v4l2_fract aspect_ratio;
+ enum v4l2_field field;
unsigned int sizeimage;
unsigned int sequence;
struct bcm2835_codec_q_data *q_data;
struct mmal_msg_event_format_changed *format =
(struct mmal_msg_event_format_changed *)mmal_buf->buffer;
+ struct mmal_parameter_video_interlace_type interlace;
+ int interlace_size = sizeof(interlace);
+ int ret;
+
v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: Format changed: buff size min %u, rec %u, buff num min %u, rec %u\n",
__func__,
format->buffer_size_min,
q_data->aspect_ratio.numerator = format->es.video.par.num;
q_data->aspect_ratio.denominator = format->es.video.par.den;
+ ret = vchiq_mmal_port_parameter_get(ctx->dev->instance,
+ &ctx->component->output[0],
+ MMAL_PARAMETER_VIDEO_INTERLACE_TYPE,
+ &interlace,
+ &interlace_size);
+ if (!ret) {
+ switch (interlace.mode) {
+ case MMAL_INTERLACE_PROGRESSIVE:
+ default:
+ q_data->field = V4L2_FIELD_NONE;
+ break;
+ case MMAL_INTERLACE_FIELDS_INTERLEAVED_UPPER_FIRST:
+ q_data->field = V4L2_FIELD_INTERLACED_TB;
+ break;
+ case MMAL_INTERLACE_FIELDS_INTERLEAVED_LOWER_FIRST:
+ q_data->field = V4L2_FIELD_INTERLACED_BT;
+ break;
+ }
+ v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: interlace mode %u, v4l2 field %u\n",
+ __func__, interlace.mode, q_data->field);
+ } else {
+ q_data->field = V4L2_FIELD_NONE;
+ }
+
queue_res_chg_event(ctx);
}
vb2->vb2_buf.timestamp = mmal_buf->pts * 1000;
vb2_set_plane_payload(&vb2->vb2_buf, 0, mmal_buf->length);
+ switch (mmal_buf->mmal_flags &
+ (MMAL_BUFFER_HEADER_VIDEO_FLAG_INTERLACED |
+ MMAL_BUFFER_HEADER_VIDEO_FLAG_TOP_FIELD_FIRST)) {
+ case 0:
+ case MMAL_BUFFER_HEADER_VIDEO_FLAG_TOP_FIELD_FIRST: /* Bogus */
+ vb2->field = V4L2_FIELD_NONE;
+ break;
+ case MMAL_BUFFER_HEADER_VIDEO_FLAG_INTERLACED:
+ vb2->field = V4L2_FIELD_INTERLACED_BT;
+ break;
+ case (MMAL_BUFFER_HEADER_VIDEO_FLAG_INTERLACED |
+ MMAL_BUFFER_HEADER_VIDEO_FLAG_TOP_FIELD_FIRST):
+ vb2->field = V4L2_FIELD_INTERLACED_TB;
+ break;
+ }
+
if (mmal_buf->mmal_flags & MMAL_BUFFER_HEADER_FLAG_KEYFRAME)
vb2->flags |= V4L2_BUF_FLAG_KEYFRAME;
f->fmt.pix_mp.width = q_data->crop_width;
f->fmt.pix_mp.height = q_data->height;
f->fmt.pix_mp.pixelformat = q_data->fmt->fourcc;
- f->fmt.pix_mp.field = V4L2_FIELD_NONE;
+ f->fmt.pix_mp.field = q_data->field;
f->fmt.pix_mp.colorspace = ctx->colorspace;
f->fmt.pix_mp.plane_fmt[0].sizeimage = q_data->sizeimage;
f->fmt.pix_mp.plane_fmt[0].bytesperline = q_data->bytesperline;
memset(f->fmt.pix_mp.plane_fmt[0].reserved, 0,
sizeof(f->fmt.pix_mp.plane_fmt[0].reserved));
- f->fmt.pix_mp.field = V4L2_FIELD_NONE;
+ if (ctx->dev->role == DECODE) {
+ switch (f->fmt.pix_mp.field) {
+ /*
+ * All of this is pretty much guesswork as we'll set the
+ * interlace format correctly come format changed, and signal
+ * it appropriately on each buffer.
+ */
+ default:
+ case V4L2_FIELD_NONE:
+ case V4L2_FIELD_ANY:
+ f->fmt.pix_mp.field = V4L2_FIELD_NONE;
+ break;
+ case V4L2_FIELD_INTERLACED:
+ f->fmt.pix_mp.field = V4L2_FIELD_INTERLACED;
+ break;
+ case V4L2_FIELD_TOP:
+ case V4L2_FIELD_BOTTOM:
+ case V4L2_FIELD_INTERLACED_TB:
+ f->fmt.pix_mp.field = V4L2_FIELD_INTERLACED_TB;
+ break;
+ case V4L2_FIELD_INTERLACED_BT:
+ f->fmt.pix_mp.field = V4L2_FIELD_INTERLACED_BT;
+ break;
+ }
+ } else {
+ f->fmt.pix_mp.field = V4L2_FIELD_NONE;
+ }
return 0;
}
ctx->ycbcr_enc = f->fmt.pix_mp.ycbcr_enc;
ctx->quant = f->fmt.pix_mp.quantization;
+ q_data->field = f->fmt.pix_mp.field;
+
/* All parameters should have been set correctly by try_fmt */
q_data->bytesperline = f->fmt.pix_mp.plane_fmt[0].bytesperline;
q_data->sizeimage = f->fmt.pix_mp.plane_fmt[0].sizeimage;
if (V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
if (vbuf->field == V4L2_FIELD_ANY)
vbuf->field = V4L2_FIELD_NONE;
- if (vbuf->field != V4L2_FIELD_NONE) {
- v4l2_err(&ctx->dev->v4l2_dev, "%s field isn't supported\n",
- __func__);
- return -EINVAL;
- }
}
if (vb2_plane_size(vb, 0) < q_data->sizeimage) {
ctx->q_data[V4L2_M2M_SRC].crop_width,
ctx->q_data[V4L2_M2M_SRC].height,
ctx->q_data[V4L2_M2M_SRC].fmt);
+ ctx->q_data[V4L2_M2M_SRC].field = V4L2_FIELD_NONE;
ctx->q_data[V4L2_M2M_DST].crop_width = DEFAULT_WIDTH;
ctx->q_data[V4L2_M2M_DST].crop_height = DEFAULT_HEIGHT;
ctx->q_data[V4L2_M2M_DST].fmt);
ctx->q_data[V4L2_M2M_DST].aspect_ratio.numerator = 1;
ctx->q_data[V4L2_M2M_DST].aspect_ratio.denominator = 1;
+ ctx->q_data[V4L2_M2M_DST].field = V4L2_FIELD_NONE;
ctx->colorspace = V4L2_COLORSPACE_REC709;
ctx->bitrate = 10 * 1000 * 1000;