summaryrefslogtreecommitdiff
path: root/libavformat/rtpdec_rfc4175.c
diff options
context:
space:
mode:
authorLimin Wang <lance.lmwang@gmail.com>2022-01-01 20:19:40 +0800
committerLimin Wang <lance.lmwang@gmail.com>2022-01-12 09:21:06 +0800
commit824fdd0f89b7ffe2753bf648e8c56cf09a71edf0 (patch)
tree1824358127c8d3c497eb2a51f1438d4a2051bc2d /libavformat/rtpdec_rfc4175.c
parent52f70261642725f2b1af6e1a5a0b2c9d868997fa (diff)
downloadffmpeg-824fdd0f89b7ffe2753bf648e8c56cf09a71edf0.tar.gz
avformat/rtpdec_rfc4175: support for interlace format
Signed-off-by: Limin Wang <lance.lmwang@gmail.com>
Diffstat (limited to 'libavformat/rtpdec_rfc4175.c')
-rw-r--r--libavformat/rtpdec_rfc4175.c25
1 files changed, 21 insertions, 4 deletions
diff --git a/libavformat/rtpdec_rfc4175.c b/libavformat/rtpdec_rfc4175.c
index a66e00d5fe..e0a708e437 100644
--- a/libavformat/rtpdec_rfc4175.c
+++ b/libavformat/rtpdec_rfc4175.c
@@ -33,6 +33,8 @@ struct PayloadContext {
int depth;
int width;
int height;
+ int interlaced;
+ int field;
uint8_t *frame;
unsigned int frame_size;
@@ -104,6 +106,11 @@ static int rfc4175_parse_format(AVStream *stream, PayloadContext *data)
stream->codecpar->bits_per_coded_sample = av_get_bits_per_pixel(desc);
data->frame_size = data->width * data->height * data->pgroup / data->xinc;
+ if (data->interlaced)
+ stream->codecpar->field_order = AV_FIELD_TT;
+ else
+ stream->codecpar->field_order = AV_FIELD_PROGRESSIVE;
+
if (data->framerate.den > 0) {
stream->avg_frame_rate = data->framerate;
stream->codecpar->bit_rate = data->frame_size * av_q2d(data->framerate) * 8;
@@ -124,6 +131,8 @@ static int rfc4175_parse_fmtp(AVFormatContext *s, AVStream *stream,
data->sampling = av_strdup(value);
else if (!strncmp(attr, "depth", 5))
data->depth = atoi(value);
+ else if (!strncmp(attr, "interlace", 9))
+ data->interlaced = 1;
else if (!strncmp(attr, "exactframerate", 14)) {
if (av_parse_video_rate(&data->framerate, value) < 0)
return AVERROR(EINVAL);
@@ -195,15 +204,18 @@ static int rfc4175_parse_sdp_line(AVFormatContext *s, int st_index,
static int rfc4175_finalize_packet(PayloadContext *data, AVPacket *pkt,
int stream_index)
{
- int ret;
+ int ret = 0;
pkt->stream_index = stream_index;
+ if (!data->interlaced || data->field) {
ret = av_packet_from_data(pkt, data->frame, data->frame_size);
if (ret < 0) {
av_freep(&data->frame);
}
-
data->frame = NULL;
+ }
+
+ data->field = 0;
return ret;
}
@@ -213,7 +225,7 @@ static int rfc4175_handle_packet(AVFormatContext *ctx, PayloadContext *data,
const uint8_t * buf, int len,
uint16_t seq, int flags)
{
- int length, line, offset, cont;
+ int length, line, offset, cont, field;
const uint8_t *headers = buf + 2; /* skip extended seqnum */
const uint8_t *payload = buf + 2;
int payload_len = len - 2;
@@ -266,10 +278,12 @@ static int rfc4175_handle_packet(AVFormatContext *ctx, PayloadContext *data,
return AVERROR_INVALIDDATA;
length = (headers[0] << 8) | headers[1];
+ field = (headers[2] & 0x80) >> 7;
line = ((headers[2] & 0x7f) << 8) | headers[3];
offset = ((headers[4] & 0x7f) << 8) | headers[5];
cont = headers[4] & 0x80;
headers += 6;
+ data->field = field;
if (!data->pgroup || length % data->pgroup)
return AVERROR_INVALIDDATA;
@@ -277,9 +291,12 @@ static int rfc4175_handle_packet(AVFormatContext *ctx, PayloadContext *data,
if (length > payload_len)
length = payload_len;
+ if (data->interlaced)
+ line = 2 * line + field;
+
/* prevent ill-formed packets to write after buffer's end */
copy_offset = (line * data->width + offset) * data->pgroup / data->xinc;
- if (copy_offset + length > data->frame_size)
+ if (copy_offset + length > data->frame_size || !data->frame)
return AVERROR_INVALIDDATA;
dest = data->frame + copy_offset;