FFmpeg
apv_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 "libavutil/avassert.h"
20 #include "libavutil/buffer.h"
21 #include "libavutil/mem.h"
22 
23 #include "avcodec.h"
24 #include "apv.h"
25 #include "cbs.h"
26 #include "cbs_apv.h"
27 #include "parser.h"
28 #include "parser_internal.h"
29 
30 typedef struct APVParseContext {
32 
36 
37 static const enum AVPixelFormat apv_format_table[5][5] = {
39  { 0 }, // 4:2:0 is not valid.
43 };
44 
45 static int find_frame_end(APVParseContext *p, const uint8_t *buf, int buf_size)
46 {
47  ParseContext *pc = &p->pc;
48  int pic_found, i = 0;
49  uint32_t state;
50 
51  pic_found = pc->frame_start_found;
52  state = pc->state;
53 
54  if (buf_size == 0) {
55  pc->frame_start_found = 0;
56  pc->state = -1;
57  return 0;
58  }
59 
60  if (!pic_found) {
61  for (; i < buf_size; i++) {
62  state = (state << 8) | buf[i];
63  if (state == APV_SIGNATURE) {
64  i++;
65  pic_found = 1;
66  break;
67  }
68  }
69  }
70 
71  if (pic_found) {
72  for(; i < buf_size; i++) {
73  state = (state << 8) | buf[i];
74  if (state == APV_SIGNATURE) {
75  pc->frame_start_found = 0;
76  pc->state = -1;
77  return i - 3;
78  }
79  }
80  }
81 
82  pc->frame_start_found = pic_found;
83  pc->state = state;
84  return END_NOT_FOUND;
85 }
86 
87 static void dummy_free(void *opaque, uint8_t *data)
88 {
89  av_assert0(opaque == data);
90 }
91 
93  AVCodecContext *avctx,
94  const uint8_t **poutbuf, int *poutbuf_size,
95  const uint8_t *buf, int buf_size)
96 {
97  APVParseContext *p = s->priv_data;
98  CodedBitstreamFragment *au = &p->au;
99  AVBufferRef *ref = NULL;
100  int next, ret;
101 
102  if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) {
103  next = buf_size;
104  } else {
105  next = find_frame_end(p, buf, buf_size);
106 
107  if (ff_combine_frame(&p->pc, next, &buf, &buf_size) < 0) {
108  *poutbuf = NULL;
109  *poutbuf_size = 0;
110  return buf_size;
111  }
112  }
113 
114  *poutbuf = buf;
115  *poutbuf_size = buf_size;
116 
117  if (!buf_size)
118  return 0;
119 
120  ref = av_buffer_create((uint8_t *)buf, buf_size, dummy_free,
121  (void *)buf, AV_BUFFER_FLAG_READONLY);
122  if (!ref)
123  return next;
124 
125  p->cbc->log_ctx = avctx;
126 
127  ret = ff_cbs_read(p->cbc, au, ref, buf, buf_size);
128  if (ret < 0) {
129  av_log(avctx, AV_LOG_ERROR, "Failed to parse access unit.\n");
130  goto end;
131  }
132 
133  s->key_frame = 1;
134  s->pict_type = AV_PICTURE_TYPE_I;
135  s->field_order = AV_FIELD_UNKNOWN;
136  s->picture_structure = AV_PICTURE_STRUCTURE_FRAME;
137 
138  for (int i = 0; i < au->nb_units; i++) {
139  const CodedBitstreamUnit *pbu = &au->units[i];
140 
141  switch (pbu->type) {
142  case APV_PBU_PRIMARY_FRAME: {
143  const APVRawFrame *frame = pbu->content;
144  const APVRawFrameHeader *header = &frame->frame_header;
145  const APVRawFrameInfo *info = &header->frame_info;
146  int bit_depth = info->bit_depth_minus8 + 8;
147 
148  if (bit_depth < 8 || bit_depth > 16 || bit_depth % 2)
149  break;
150 
151  s->width = info->frame_width;
152  s->height = info->frame_height;
153  s->format = apv_format_table[info->chroma_format_idc][bit_depth - 4 >> 2];
154  avctx->profile = info->profile_idc;
155  avctx->level = info->level_idc;
157  avctx->color_primaries = header->color_primaries;
158  avctx->color_trc = header->transfer_characteristics;
159  avctx->colorspace = header->matrix_coefficients;
160  avctx->color_range = header->full_range_flag ? AVCOL_RANGE_JPEG
162  goto end;
163  }
164  default:
165  break;
166  }
167  }
168 
169 end:
170  ff_cbs_fragment_reset(au);
173  p->cbc->log_ctx = NULL;
174 
175  return next;
176 }
177 
180 };
181 
183 {
184  APVParseContext *p = s->priv_data;
185  int ret;
186 
187  ret = ff_cbs_init(&p->cbc, AV_CODEC_ID_APV, NULL);
188  if (ret < 0)
189  return ret;
190 
191  p->cbc->decompose_unit_types = decompose_unit_types;
192  p->cbc->nb_decompose_unit_types = FF_ARRAY_ELEMS(decompose_unit_types);
193 
194  return 0;
195 }
196 
198 {
199  APVParseContext *p = s->priv_data;
200  ParseContext *pc = &p->pc;
201 
202  av_freep(&pc->buffer);
203  ff_cbs_fragment_free(&p->au);
204  ff_cbs_close(&p->cbc);
205 }
206 
209  .priv_data_size = sizeof(APVParseContext),
210  .init = init,
211  .parse = parse,
212  .close = close,
213 };
cbs.h
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
ff_apv_parser
const FFCodecParser ff_apv_parser
Definition: apv_parser.c:207
AVCodecContext::colorspace
enum AVColorSpace colorspace
YUV colorspace type.
Definition: avcodec.h:667
find_frame_end
static int find_frame_end(APVParseContext *p, const uint8_t *buf, int buf_size)
Definition: apv_parser.c:45
CodedBitstreamUnit::content
void * content
Pointer to the decomposed form of this unit.
Definition: cbs.h:114
parser_internal.h
AVCodecContext::color_trc
enum AVColorTransferCharacteristic color_trc
Color Transfer Characteristic.
Definition: avcodec.h:660
AVCOL_RANGE_JPEG
@ AVCOL_RANGE_JPEG
Full range content.
Definition: pixfmt.h:777
CodedBitstreamContext
Context structure for coded bitstream operations.
Definition: cbs.h:226
data
const char data[16]
Definition: mxf.c:149
CodedBitstreamUnit::type
CodedBitstreamUnitType type
Codec-specific type of this unit.
Definition: cbs.h:81
bit_depth
static void bit_depth(AudioStatsContext *s, const uint64_t *const mask, uint8_t *depth)
Definition: af_astats.c:246
ParseContext::state
uint32_t state
contains the last few bytes in MSB order
Definition: parser.h:33
APV_SIGNATURE
#define APV_SIGNATURE
Definition: apv.h:23
CodedBitstreamUnit
Coded bitstream unit structure.
Definition: cbs.h:77
close
static av_cold void close(AVCodecParserContext *s)
Definition: apv_parser.c:197
ParseContext
Definition: parser.h:28
AV_PIX_FMT_YUVA444P16
#define AV_PIX_FMT_YUVA444P16
Definition: pixfmt.h:597
AV_PIX_FMT_GRAY16
#define AV_PIX_FMT_GRAY16
Definition: pixfmt.h:522
AV_PIX_FMT_YUV444P10
#define AV_PIX_FMT_YUV444P10
Definition: pixfmt.h:542
ParseContext::buffer
uint8_t * buffer
Definition: parser.h:29
CodedBitstreamFragment::units
CodedBitstreamUnit * units
Pointer to an array of units of length nb_units_allocated.
Definition: cbs.h:175
avassert.h
AV_PICTURE_STRUCTURE_FRAME
@ AV_PICTURE_STRUCTURE_FRAME
coded as frame
Definition: avcodec.h:2586
AVCodecContext::color_primaries
enum AVColorPrimaries color_primaries
Chromaticity coordinates of the source primaries.
Definition: avcodec.h:653
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
av_cold
#define av_cold
Definition: attributes.h:106
decompose_unit_types
static const CodedBitstreamUnitType decompose_unit_types[]
Definition: apv_parser.c:178
AV_PIX_FMT_YUV422P16
#define AV_PIX_FMT_YUV422P16
Definition: pixfmt.h:551
AV_FIELD_UNKNOWN
@ AV_FIELD_UNKNOWN
Definition: defs.h:212
CodedBitstreamFragment
Coded bitstream fragment structure, combining one or more units.
Definition: cbs.h:129
s
#define s(width, name)
Definition: cbs_vp9.c:198
AV_PIX_FMT_YUV444P16
#define AV_PIX_FMT_YUV444P16
Definition: pixfmt.h:552
AV_BUFFER_FLAG_READONLY
#define AV_BUFFER_FLAG_READONLY
Always treat the buffer as read-only, even when it has only one reference.
Definition: buffer.h:114
APVRawFrameInfo
Definition: cbs_apv.h:43
info
MIPS optimizations info
Definition: mips.txt:2
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:41
CodedBitstreamUnitType
uint32_t CodedBitstreamUnitType
The codec-specific type of a bitstream unit.
Definition: cbs.h:54
AV_PIX_FMT_YUVA444P12
#define AV_PIX_FMT_YUVA444P12
Definition: pixfmt.h:594
init
static av_cold int init(AVCodecParserContext *s)
Definition: apv_parser.c:182
AV_PIX_FMT_GRAY14
#define AV_PIX_FMT_GRAY14
Definition: pixfmt.h:521
APVParseContext::au
CodedBitstreamFragment au
Definition: apv_parser.c:34
APVParseContext::cbc
CodedBitstreamContext * cbc
Definition: apv_parser.c:33
AV_PIX_FMT_GRAY10
#define AV_PIX_FMT_GRAY10
Definition: pixfmt.h:519
NULL
#define NULL
Definition: coverity.c:32
AVCodecContext::color_range
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition: avcodec.h:677
av_buffer_unref
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
Definition: buffer.c:139
AVCHROMA_LOC_TOPLEFT
@ AVCHROMA_LOC_TOPLEFT
ITU-R 601, SMPTE 274M 296M S314M(DV 4:1:1), mpeg2 4:2:2.
Definition: pixfmt.h:800
apv.h
apv_format_table
static enum AVPixelFormat apv_format_table[5][5]
Definition: apv_parser.c:37
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:92
AVCodecContext::level
int level
Encoding level descriptor.
Definition: avcodec.h:1636
APVRawFrame
Definition: cbs_apv.h:101
av_buffer_create
AVBufferRef * av_buffer_create(uint8_t *data, size_t size, void(*free)(void *opaque, uint8_t *data), void *opaque, int flags)
Create an AVBuffer from an existing array.
Definition: buffer.c:55
dummy_free
static void dummy_free(void *opaque, uint8_t *data)
Definition: apv_parser.c:87
APV_PBU_PRIMARY_FRAME
@ APV_PBU_PRIMARY_FRAME
Definition: apv.h:27
APVRawFrameHeader
Definition: cbs_apv.h:67
AV_PIX_FMT_YUV422P12
#define AV_PIX_FMT_YUV422P12
Definition: pixfmt.h:544
AV_PIX_FMT_YUV444P12
#define AV_PIX_FMT_YUV444P12
Definition: pixfmt.h:546
state
static struct @547 state
header
static const uint8_t header[24]
Definition: sdr2.c:68
buffer.h
AV_PIX_FMT_YUVA444P
@ AV_PIX_FMT_YUVA444P
planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
Definition: pixfmt.h:174
AV_PIX_FMT_YUVA444P10
#define AV_PIX_FMT_YUVA444P10
Definition: pixfmt.h:592
av_buffer_get_ref_count
int av_buffer_get_ref_count(const AVBufferRef *buf)
Definition: buffer.c:160
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
APVParseContext
Definition: apv_parser.c:30
PARSER_FLAG_COMPLETE_FRAMES
#define PARSER_FLAG_COMPLETE_FRAMES
Definition: avcodec.h:2623
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
av_assert1
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition: avassert.h:57
parser.h
AVCodecContext::chroma_sample_location
enum AVChromaLocation chroma_sample_location
This defines the location of chroma samples.
Definition: avcodec.h:684
PARSER_CODEC_LIST
#define PARSER_CODEC_LIST(...)
Definition: parser_internal.h:76
AVCOL_RANGE_MPEG
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition: pixfmt.h:760
avcodec.h
AVCodecParserContext
Definition: avcodec.h:2589
ret
ret
Definition: filter_design.txt:187
AV_CODEC_ID_APV
@ AV_CODEC_ID_APV
Definition: codec_id.h:332
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:265
APVParseContext::pc
ParseContext pc
Definition: apv_parser.c:31
AVCodecContext
main external API structure.
Definition: avcodec.h:439
AVCodecContext::profile
int profile
profile
Definition: avcodec.h:1626
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:117
Windows::Graphics::DirectX::Direct3D11::p
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
Definition: vsrc_gfxcapture_winrt.hpp:53
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
mem.h
AVBufferRef
A reference to a data buffer.
Definition: buffer.h:82
END_NOT_FOUND
#define END_NOT_FOUND
Definition: parser.h:40
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AV_PIX_FMT_GRAY12
#define AV_PIX_FMT_GRAY12
Definition: pixfmt.h:520
cbs_apv.h
CodedBitstreamFragment::nb_units
int nb_units
Number of units in this fragment.
Definition: cbs.h:160