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 void 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  AV_WB16(&rtp_ctx->buf[0], 0); /* extended sequence number */
41  AV_WB8 (&rtp_ctx->buf[2], i ? (f ? (0x03) : (0x02)) : 0x00); /* flags: interlaced, second field */
42  AV_WB8 (&rtp_ctx->buf[3], parse_code);
43  if (size > 0)
44  memcpy(&rtp_ctx->buf[4 + info_hdr_size], buf, size);
45  ff_rtp_send_data(ctx, rtp_ctx->buf, RTP_VC2HQ_PL_HEADER_SIZE + info_hdr_size + size, rtp_m);
46 }
47 
48 static int send_picture(AVFormatContext *ctx, const uint8_t *buf, int size, int interlaced)
49 {
50  RTPMuxContext *rtp_ctx = ctx->priv_data;
51  GetBitContext gc;
52  int lvl, second_field;
53  uint32_t pic_nr, wavelet_depth, prefix_bytes, size_scaler;
54  uint16_t frag_len;
55  char *info_hdr = &rtp_ctx->buf[4];
56 
57  if (size < DIRAC_PIC_NR_SIZE)
58  return AVERROR(EINVAL);
59 
60  pic_nr = AV_RB32(&buf[0]);
61  buf += DIRAC_PIC_NR_SIZE;
63  second_field = interlaced && (pic_nr & 0x01);
64 
65  init_get_bits(&gc, buf, 8 * size);
66  get_interleaved_ue_golomb(&gc); /* wavelet_idx */
67  wavelet_depth = get_interleaved_ue_golomb(&gc);
68  get_interleaved_ue_golomb(&gc); /* num_x */
69  get_interleaved_ue_golomb(&gc); /* num_y */
70  prefix_bytes = get_interleaved_ue_golomb(&gc);
71  size_scaler = get_interleaved_ue_golomb(&gc);
72  /* pass the quantization matrices */
74  for(lvl = 0; lvl < wavelet_depth; lvl++)
75  {
79  }
80 
81  frag_len = (get_bits_count(&gc) + 7) / 8; /* length of transform parameters */
82 
83  AV_WB32(&info_hdr[ 0], pic_nr);
84  AV_WB16(&info_hdr[ 4], prefix_bytes);
85  AV_WB16(&info_hdr[ 6], size_scaler);
86  AV_WB16(&info_hdr[ 8], frag_len);
87  AV_WB16(&info_hdr[10], 0 /* nr. of slices */);
88  send_packet(ctx, DIRAC_RTP_PCODE_HQ_PIC_FRAGMENT, 12, buf, frag_len, interlaced, second_field, 0);
89  buf += frag_len;
90  size -= frag_len;
91 
92  while (size > 0) {
93  frag_len = FFMIN(rtp_ctx->max_payload_size - 20 /* pl header */, size);
94  AV_WB16(&info_hdr[ 8], frag_len);
95  AV_WB16(&info_hdr[10], 1 /* nr. of slices */);
96  AV_WB16(&info_hdr[12], 0 /* slice x */);
97  AV_WB16(&info_hdr[14], 0 /* slice y */);
98 
99  size -= frag_len;
100  send_packet(ctx, DIRAC_RTP_PCODE_HQ_PIC_FRAGMENT, 16, buf, frag_len, interlaced, second_field, size > 0 ? 0 : 1);
101  buf += frag_len;
102  }
103  return 0;
104 }
105 
106 void ff_rtp_send_vc2hq(AVFormatContext *ctx, const uint8_t *frame_buf, int frame_size, int interlaced)
107 {
108  const uint8_t *end = frame_buf + frame_size;
109  const uint8_t *unit = frame_buf;
110  uint8_t parse_code;
111  uint32_t unit_size;
112 
113  while (unit < end) {
114  parse_code = unit[4];
115  unit_size = AV_RB32(&unit[5]);
116 
117  if (unit_size > end - unit)
118  break;
119 
120  switch (parse_code) {
121  /* sequence header */
122  /* end of sequence */
124  case DIRAC_PCODE_END_SEQ:
125  if (unit_size >= DIRAC_DATA_UNIT_HEADER_SIZE)
126  send_packet(ctx, parse_code, 0, unit + DIRAC_DATA_UNIT_HEADER_SIZE, unit_size - DIRAC_DATA_UNIT_HEADER_SIZE, 0, 0, 0);
127  break;
128  /* HQ picture */
130  if (unit_size >= DIRAC_DATA_UNIT_HEADER_SIZE)
132  break;
133  /* parse codes without specification */
134  case DIRAC_PCODE_AUX:
135  case DIRAC_PCODE_PAD:
136  break;
137  default:
138  avpriv_report_missing_feature(ctx, "VC-2 parse code %d", parse_code);
139  break;
140  }
141  unit += unit_size;
142  }
143 }
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:266
get_interleaved_ue_golomb
static unsigned get_interleaved_ue_golomb(GetBitContext *gb)
Definition: golomb.h:143
ff_rtp_send_data
void ff_rtp_send_data(AVFormatContext *s1, const uint8_t *buf1, int len, int m)
Definition: rtpenc.c:335
init_get_bits
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition: get_bits.h:514
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:48
GetBitContext
Definition: get_bits.h:108
dirac.h
RTP_VC2HQ_PL_HEADER_SIZE
#define RTP_VC2HQ_PL_HEADER_SIZE
Definition: rtpenc_vc2hq.c:30
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:2422
ctx
AVFormatContext * ctx
Definition: movenc.c:48
get_bits.h
AVFormatContext
Format I/O context.
Definition: avformat.h:1255
AV_WB16
#define AV_WB16(p, v)
Definition: intreadwrite.h:403
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:417
f
f
Definition: af_crystalizer.c:121
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:106
send_packet
static void 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
DIRAC_PCODE_SEQ_HEADER
@ DIRAC_PCODE_SEQ_HEADER
Definition: dirac.h:62
interlaced
uint8_t interlaced
Definition: mxfenc.c:2263
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
rtpenc.h
AV_WB8
#define AV_WB8(p, d)
Definition: intreadwrite.h:394
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
DIRAC_PCODE_PICTURE_HQ
@ DIRAC_PCODE_PICTURE_HQ
Definition: dirac.h:69
AVFormatContext::priv_data
void * priv_data
Format private data.
Definition: avformat.h:1283