FFmpeg
jpegxs_parser.c
Go to the documentation of this file.
1 /*
2  * This file is part of FFmpeg.
3  *
4  * FFmpeg is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * FFmpeg is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with FFmpeg; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 #include "bytestream.h"
20 #include "get_bits.h"
21 #include "jpegxs.h"
22 #include "parser.h"
23 #include "parser_internal.h"
24 
25 /**
26  * Find the end of the current frame in the bitstream.
27  * @return the position of the first byte of the next frame, or -1
28  */
29 static int jpegxs_find_frame_end(ParseContext *pc, const uint8_t *buf,
30  int buf_size)
31 {
32  int pic_found, i = 0;
33  uint32_t state;
34 
35  pic_found = pc->frame_start_found;
36  state = pc->state;
37 
38  if (!pic_found) {
39  for (i = 0; i < buf_size; i++) {
40  state = (state << 8) | buf[i];
41  if ((uint16_t)state == JPEGXS_MARKER_SOC) {
42  i++;
43  pic_found = 1;
44  break;
45  }
46  }
47  }
48 
49  if (pic_found) {
50  if (buf_size == 0)
51  return 0;
52  for(; i < buf_size; i++) {
53  state = (state << 8) | buf[i];
54  if ((uint16_t)state == JPEGXS_MARKER_EOC) {
55  pc->frame_start_found = 0;
56  pc->state = -1;
57  return i + 1;
58  }
59  }
60  }
61 
62  pc->frame_start_found = pic_found;
63  pc->state = state;
64  return END_NOT_FOUND;
65 }
66 
68  const uint8_t *buf, int buf_size)
69 {
70  GetByteContext gbc;
71  GetBitContext gb;
72  int8_t bpc[3], log2_chroma_w[3], log2_chroma_h[3];
73  int size, marker, components;
74 
75  s->key_frame = 1;
76  s->pict_type = AV_PICTURE_TYPE_I;
77 
78  if (buf_size < 4)
79  return 0;
80 
81  bytestream2_init(&gbc, buf, buf_size);
82  marker = bytestream2_get_be16(&gbc);
83  if (marker != JPEGXS_MARKER_SOC)
84  return 0;
85 
86  marker = bytestream2_get_be16(&gbc);
87  if (marker != JPEGXS_MARKER_CAP)
88  return 0;
89  size = bytestream2_get_be16(&gbc);
90  bytestream2_skip(&gbc, FFMAX(size - 2, 0));
91 
92  marker = bytestream2_get_be16(&gbc);
93  if (marker != JPEGXS_MARKER_PIH)
94  return 0;
95  size = bytestream2_get_be16(&gbc);
96  bytestream2_skip(&gbc, 4); // Lcod
97  bytestream2_skip(&gbc, 2); // Ppih
98  bytestream2_skip(&gbc, 2); // Plev
99  size -= 8;
100 
101  s->width = bytestream2_get_be16(&gbc);
102  s->height = bytestream2_get_be16(&gbc);
103  size -= 4;
104 
105  bytestream2_skip(&gbc, 2); // Cw
106  bytestream2_skip(&gbc, 2); // Hsl
107  size -= 4;
108 
109  components = bytestream2_get_byte(&gbc);
110  if (components != 1 && components != 3)
111  return 0;
112  size--;
113 
114  bytestream2_skip(&gbc, FFMAX(size - 2, 0));
115 
116  while (bytestream2_get_bytes_left(&gbc) > 0) {
117  marker = bytestream2_get_be16(&gbc);
118 
119  switch(marker) {
120  case JPEGXS_MARKER_CDT:
121  size = bytestream2_get_be16(&gbc);
122  init_get_bits8(&gb, gbc.buffer, FFMIN(FFMAX(size - 2, 0), bytestream2_get_bytes_left(&gbc)));
123 
124  for (int i = 0; i < components; i++) {
125  bpc[i] = get_bits(&gb, 8);
126  if (i && bpc[i] != bpc[i-1])
127  return 0;
128 
129  log2_chroma_w[i] = get_bits(&gb, 4);
130  log2_chroma_h[i] = get_bits(&gb, 4);
131 
132  if (log2_chroma_h[i] > log2_chroma_w[i])
133  return 0;
134  if (i == 2 && (log2_chroma_h[2] != log2_chroma_h[1] ||
135  log2_chroma_w[2] != log2_chroma_w[1]))
136  return 0;
137  }
138 
139  switch (bpc[0]) {
140  case 8:
141  if (components == 1) s->format = AV_PIX_FMT_GRAY8;
142  else if (log2_chroma_w[1] == 1 && log2_chroma_h[1] == 1) s->format = AV_PIX_FMT_YUV444P;
143  else if (log2_chroma_w[1] == 2 && log2_chroma_h[1] == 1) s->format = AV_PIX_FMT_YUV422P;
144  else s->format = AV_PIX_FMT_YUV420P;
145  break;
146  case 10:
147  if (components == 1) s->format = AV_PIX_FMT_GRAY10;
148  else if (log2_chroma_w[1] == 1 && log2_chroma_h[1] == 1) s->format = AV_PIX_FMT_YUV444P10;
149  else if (log2_chroma_w[1] == 2 && log2_chroma_h[1] == 1) s->format = AV_PIX_FMT_YUV422P10;
150  else s->format = AV_PIX_FMT_YUV420P10;
151  break;
152  case 12:
153  if (components == 1) s->format = AV_PIX_FMT_GRAY12;
154  else if (log2_chroma_w[1] == 1 && log2_chroma_h[1] == 1) s->format = AV_PIX_FMT_YUV444P12;
155  else if (log2_chroma_w[1] == 2 && log2_chroma_h[1] == 1) s->format = AV_PIX_FMT_YUV422P12;
156  else s->format = AV_PIX_FMT_YUV420P12;
157  break;
158  case 14:
159  if (components == 1) s->format = AV_PIX_FMT_GRAY14;
160  else if (log2_chroma_w[1] == 1 && log2_chroma_h[1] == 1) s->format = AV_PIX_FMT_YUV444P14;
161  else if (log2_chroma_w[1] == 2 && log2_chroma_h[1] == 1) s->format = AV_PIX_FMT_YUV422P14;
162  else s->format = AV_PIX_FMT_YUV420P14;
163  break;
164  default:
165  s->format = AV_PIX_FMT_NONE;
166  break;
167  }
168  return 0;
169  default:
170  size = bytestream2_get_be16(&gbc);
171  bytestream2_skip(&gbc, FFMAX(size - 2, 0));
172  break;
173  }
174  }
175 
176  return 0;
177 }
178 
180  AVCodecContext *avctx,
181  const uint8_t **poutbuf, int *poutbuf_size,
182  const uint8_t *buf, int buf_size)
183 {
184  ParseContext *pc = s->priv_data;
185  int next;
186 
187  next = jpegxs_find_frame_end(pc, buf, buf_size);
188 
189  if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
190  *poutbuf = NULL;
191  *poutbuf_size = 0;
192  return buf_size;
193  }
194 
195  jpegxs_parse_frame(s, avctx, buf, buf_size);
196 
197  *poutbuf = buf;
198  *poutbuf_size = buf_size;
199  return next;
200 }
201 
204  .priv_data_size = sizeof(ParseContext),
207 };
bytestream2_get_bytes_left
static av_always_inline int bytestream2_get_bytes_left(const GetByteContext *g)
Definition: bytestream.h:158
GetByteContext
Definition: bytestream.h:33
ff_parse_close
av_cold void ff_parse_close(AVCodecParserContext *s)
Definition: parser.c:298
parser_internal.h
JPEGXS_MARKER_CAP
@ JPEGXS_MARKER_CAP
Definition: jpegxs.h:34
AV_PIX_FMT_YUV420P10
#define AV_PIX_FMT_YUV420P10
Definition: pixfmt.h:539
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
ParseContext::state
uint32_t state
contains the last few bytes in MSB order
Definition: parser.h:33
close
static av_cold void close(AVCodecParserContext *s)
Definition: apv_parser.c:136
bytestream2_skip
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
Definition: bytestream.h:168
get_bits
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:337
ParseContext
Definition: parser.h:28
JPEGXS_MARKER_SOC
@ JPEGXS_MARKER_SOC
Definition: jpegxs.h:23
GetBitContext
Definition: get_bits.h:109
AV_PIX_FMT_YUV444P10
#define AV_PIX_FMT_YUV444P10
Definition: pixfmt.h:542
init_get_bits8
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
Definition: get_bits.h:544
s
#define s(width, name)
Definition: cbs_vp9.c:198
GetByteContext::buffer
const uint8_t * buffer
Definition: bytestream.h:34
JPEGXS_MARKER_EOC
@ JPEGXS_MARKER_EOC
Definition: jpegxs.h:24
get_bits.h
AV_PIX_FMT_GRAY14
#define AV_PIX_FMT_GRAY14
Definition: pixfmt.h:521
AV_PIX_FMT_YUV420P
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:73
AV_PIX_FMT_GRAY10
#define AV_PIX_FMT_GRAY10
Definition: pixfmt.h:519
NULL
#define NULL
Definition: coverity.c:32
JPEGXS_MARKER_CDT
@ JPEGXS_MARKER_CDT
Definition: jpegxs.h:26
AV_PICTURE_TYPE_I
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:278
ParseContext::frame_start_found
int frame_start_found
Definition: parser.h:34
AV_PIX_FMT_YUV422P10
#define AV_PIX_FMT_YUV422P10
Definition: pixfmt.h:540
AV_PIX_FMT_GRAY8
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition: pixfmt.h:81
parse
static int parse(AVCodecParserContext *s, AVCodecContext *avctx, const uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size)
Definition: apv_parser.c:46
AV_PIX_FMT_YUV422P12
#define AV_PIX_FMT_YUV422P12
Definition: pixfmt.h:544
size
int size
Definition: twinvq_data.h:10344
AV_PIX_FMT_YUV444P12
#define AV_PIX_FMT_YUV444P12
Definition: pixfmt.h:546
ff_jpegxs_parser
const FFCodecParser ff_jpegxs_parser
Definition: jpegxs_parser.c:202
state
static struct @547 state
jpegxs_parse_frame
static int jpegxs_parse_frame(AVCodecParserContext *s, AVCodecContext *avctx, const uint8_t *buf, int buf_size)
Definition: jpegxs_parser.c:67
ff_combine_frame
int ff_combine_frame(ParseContext *pc, int next, const uint8_t **buf, int *buf_size)
Combine the (truncated) bitstream to a complete frame.
Definition: parser.c:211
FFCodecParser
Definition: parser_internal.h:29
AV_CODEC_ID_JPEGXS
@ AV_CODEC_ID_JPEGXS
Definition: codec_id.h:334
jpegxs.h
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
parser.h
PARSER_CODEC_LIST
#define PARSER_CODEC_LIST(...)
Definition: parser_internal.h:76
AVCodecParserContext
Definition: avcodec.h:2589
jpegxs_find_frame_end
static int jpegxs_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size)
Find the end of the current frame in the bitstream.
Definition: jpegxs_parser.c:29
AV_PIX_FMT_YUV420P12
#define AV_PIX_FMT_YUV420P12
Definition: pixfmt.h:543
AV_PIX_FMT_YUV422P14
#define AV_PIX_FMT_YUV422P14
Definition: pixfmt.h:548
AVCodecContext
main external API structure.
Definition: avcodec.h:439
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:72
AV_PIX_FMT_YUV444P
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:78
AV_PIX_FMT_YUV422P
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:77
jpegxsvideo_parse
static int jpegxsvideo_parse(AVCodecParserContext *s, AVCodecContext *avctx, const uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size)
Definition: jpegxs_parser.c:179
END_NOT_FOUND
#define END_NOT_FOUND
Definition: parser.h:40
JPEGXS_MARKER_PIH
@ JPEGXS_MARKER_PIH
Definition: jpegxs.h:25
bytestream.h
bytestream2_init
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:137
AV_PIX_FMT_YUV444P14
#define AV_PIX_FMT_YUV444P14
Definition: pixfmt.h:549
AV_PIX_FMT_GRAY12
#define AV_PIX_FMT_GRAY12
Definition: pixfmt.h:520
AV_PIX_FMT_YUV420P14
#define AV_PIX_FMT_YUV420P14
Definition: pixfmt.h:547