FFmpeg
rtpenc_vc2hq.c
Go to the documentation of this file.
1 /*
2  * RTP packetizer for VC-2 HQ payload format (draft version 1) - experimental
3  * Copyright (c) 2016 Thomas Volkert <thomas@netzeal.de>
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "libavutil/intreadwrite.h"
23 #include "libavcodec/dirac.h"
24 #include "libavcodec/get_bits.h"
25 #include "libavcodec/golomb.h"
26 
27 #include "avformat.h"
28 #include "rtpenc.h"
29 
30 #define RTP_VC2HQ_PL_HEADER_SIZE 4
31 
32 #define DIRAC_DATA_UNIT_HEADER_SIZE 13
33 #define DIRAC_PIC_NR_SIZE 4
34 #define DIRAC_RTP_PCODE_HQ_PIC_FRAGMENT 0xEC
35 
36 static int send_packet(AVFormatContext *ctx, uint8_t parse_code, int info_hdr_size, const uint8_t *buf, int size, int i, int f, int rtp_m)
37 {
38  RTPMuxContext *rtp_ctx = ctx->priv_data;
39 
40  if (size < 0 ||
41  size > rtp_ctx->max_payload_size - RTP_VC2HQ_PL_HEADER_SIZE - info_hdr_size) {
42  av_log(ctx, AV_LOG_ERROR, "VC-2 data unit too large for RTP payload buffer\n");
43  return AVERROR_INVALIDDATA;
44  }
45 
46  AV_WB16(&rtp_ctx->buf[0], 0); /* extended sequence number */
47  AV_WB8 (&rtp_ctx->buf[2], i ? (f ? (0x03) : (0x02)) : 0x00); /* flags: interlaced, second field */
48  AV_WB8 (&rtp_ctx->buf[3], parse_code);
49  if (size > 0)
50  memcpy(&rtp_ctx->buf[4 + info_hdr_size], buf, size);
51  ff_rtp_send_data(ctx, rtp_ctx->buf, RTP_VC2HQ_PL_HEADER_SIZE + info_hdr_size + size, rtp_m);
52  return 0;
53 }
54 
55 static int send_picture(AVFormatContext *ctx, const uint8_t *buf, int size, int interlaced)
56 {
57  RTPMuxContext *rtp_ctx = ctx->priv_data;
58  GetBitContext gc;
59  int lvl, second_field;
60  uint32_t pic_nr, wavelet_depth, prefix_bytes, size_scaler;
61  uint16_t frag_len;
62  char *info_hdr = &rtp_ctx->buf[4];
63 
64  if (size < DIRAC_PIC_NR_SIZE)
65  return AVERROR(EINVAL);
66 
67  pic_nr = AV_RB32(&buf[0]);
68  buf += DIRAC_PIC_NR_SIZE;
70  second_field = interlaced && (pic_nr & 0x01);
71 
72  init_get_bits(&gc, buf, 8 * size);
73  get_interleaved_ue_golomb(&gc); /* wavelet_idx */
74  wavelet_depth = get_interleaved_ue_golomb(&gc);
75  get_interleaved_ue_golomb(&gc); /* num_x */
76  get_interleaved_ue_golomb(&gc); /* num_y */
77  prefix_bytes = get_interleaved_ue_golomb(&gc);
78  size_scaler = get_interleaved_ue_golomb(&gc);
79  /* pass the quantization matrices */
81  for(lvl = 0; lvl < wavelet_depth; lvl++)
82  {
86  }
87 
88  frag_len = (get_bits_count(&gc) + 7) / 8; /* length of transform parameters */
89 
90  AV_WB32(&info_hdr[ 0], pic_nr);
91  AV_WB16(&info_hdr[ 4], prefix_bytes);
92  AV_WB16(&info_hdr[ 6], size_scaler);
93  AV_WB16(&info_hdr[ 8], frag_len);
94  AV_WB16(&info_hdr[10], 0 /* nr. of slices */);
95  if (send_packet(ctx, DIRAC_RTP_PCODE_HQ_PIC_FRAGMENT, 12, buf, frag_len, interlaced, second_field, 0) < 0)
96  return AVERROR_INVALIDDATA;
97  buf += frag_len;
98  size -= frag_len;
99 
100  while (size > 0) {
101  frag_len = FFMIN(rtp_ctx->max_payload_size - 20 /* pl header */, size);
102  AV_WB16(&info_hdr[ 8], frag_len);
103  AV_WB16(&info_hdr[10], 1 /* nr. of slices */);
104  AV_WB16(&info_hdr[12], 0 /* slice x */);
105  AV_WB16(&info_hdr[14], 0 /* slice y */);
106 
107  size -= frag_len;
108  if (send_packet(ctx, DIRAC_RTP_PCODE_HQ_PIC_FRAGMENT, 16, buf, frag_len, interlaced, second_field, size > 0 ? 0 : 1) < 0)
109  return AVERROR_INVALIDDATA;
110  buf += frag_len;
111  }
112  return 0;
113 }
114 
115 void ff_rtp_send_vc2hq(AVFormatContext *ctx, const uint8_t *frame_buf, int frame_size, int interlaced)
116 {
117  const uint8_t *end = frame_buf + frame_size;
118  const uint8_t *unit = frame_buf;
119  uint8_t parse_code;
120  uint32_t unit_size;
121 
122  while (unit < end) {
123  parse_code = unit[4];
124  unit_size = AV_RB32(&unit[5]);
125 
126  if (unit_size > end - unit)
127  break;
128 
129  switch (parse_code) {
130  /* sequence header */
131  /* end of sequence */
133  case DIRAC_PCODE_END_SEQ:
134  if (unit_size >= DIRAC_DATA_UNIT_HEADER_SIZE)
135  send_packet(ctx, parse_code, 0, unit + DIRAC_DATA_UNIT_HEADER_SIZE, unit_size - DIRAC_DATA_UNIT_HEADER_SIZE, 0, 0, 0);
136  break;
137  /* HQ picture */
139  if (unit_size >= DIRAC_DATA_UNIT_HEADER_SIZE)
141  break;
142  /* parse codes without specification */
143  case DIRAC_PCODE_AUX:
144  case DIRAC_PCODE_PAD:
145  break;
146  default:
147  avpriv_report_missing_feature(ctx, "VC-2 parse code %d", parse_code);
148  break;
149  }
150  unit += unit_size;
151  }
152 }
DIRAC_PCODE_PAD
@ DIRAC_PCODE_PAD
Definition: dirac.h:65
DIRAC_RTP_PCODE_HQ_PIC_FRAGMENT
#define DIRAC_RTP_PCODE_HQ_PIC_FRAGMENT
Definition: rtpenc_vc2hq.c:34
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
get_bits_count
static int get_bits_count(const GetBitContext *s)
Definition: get_bits.h:254
get_interleaved_ue_golomb
static unsigned get_interleaved_ue_golomb(GetBitContext *gb)
Definition: golomb.h:143
send_packet
static int send_packet(AVFormatContext *ctx, uint8_t parse_code, int info_hdr_size, const uint8_t *buf, int size, int i, int f, int rtp_m)
Definition: rtpenc_vc2hq.c:36
ff_rtp_send_data
void ff_rtp_send_data(AVFormatContext *s1, const uint8_t *buf1, int len, int m)
Definition: rtpenc.c:364
init_get_bits
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition: get_bits.h:517
golomb.h
exp golomb vlc stuff
send_picture
static int send_picture(AVFormatContext *ctx, const uint8_t *buf, int size, int interlaced)
Definition: rtpenc_vc2hq.c:55
GetBitContext
Definition: get_bits.h:109
dirac.h
RTP_VC2HQ_PL_HEADER_SIZE
#define RTP_VC2HQ_PL_HEADER_SIZE
Definition: rtpenc_vc2hq.c:30
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
DIRAC_PIC_NR_SIZE
#define DIRAC_PIC_NR_SIZE
Definition: rtpenc_vc2hq.c:33
DIRAC_DATA_UNIT_HEADER_SIZE
#define DIRAC_DATA_UNIT_HEADER_SIZE
Definition: rtpenc_vc2hq.c:32
intreadwrite.h
frame_size
int frame_size
Definition: mxfenc.c:2489
ctx
static AVFormatContext * ctx
Definition: movenc.c:49
get_bits.h
AVFormatContext
Format I/O context.
Definition: avformat.h:1314
AV_WB16
#define AV_WB16(p, v)
Definition: intreadwrite.h:401
RTPMuxContext
Definition: rtpenc.h:27
DIRAC_PCODE_AUX
@ DIRAC_PCODE_AUX
Definition: dirac.h:64
RTPMuxContext::buf
uint8_t * buf
Definition: rtpenc.h:49
AV_WB32
#define AV_WB32(p, v)
Definition: intreadwrite.h:415
f
f
Definition: af_crystalizer.c:122
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
size
int size
Definition: twinvq_data.h:10344
AV_RB32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_RB32
Definition: bytestream.h:96
avpriv_report_missing_feature
void avpriv_report_missing_feature(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
ff_rtp_send_vc2hq
void ff_rtp_send_vc2hq(AVFormatContext *ctx, const uint8_t *frame_buf, int frame_size, int interlaced)
Definition: rtpenc_vc2hq.c:115
DIRAC_PCODE_SEQ_HEADER
@ DIRAC_PCODE_SEQ_HEADER
Definition: dirac.h:62
interlaced
uint8_t interlaced
Definition: mxfenc.c:2336
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
rtpenc.h
AV_WB8
#define AV_WB8(p, d)
Definition: intreadwrite.h:392
avformat.h
DIRAC_PCODE_END_SEQ
@ DIRAC_PCODE_END_SEQ
Definition: dirac.h:63
RTPMuxContext::max_payload_size
int max_payload_size
Definition: rtpenc.h:38
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
DIRAC_PCODE_PICTURE_HQ
@ DIRAC_PCODE_PICTURE_HQ
Definition: dirac.h:69
AVFormatContext::priv_data
void * priv_data
Format private data.
Definition: avformat.h:1342