FFmpeg  4.0
vp9_raw_reorder_bsf.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/intmath.h"
21 #include "libavutil/log.h"
22 #include "libavutil/mem.h"
23 #include "libavutil/opt.h"
24 
25 #include "bsf.h"
26 #include "get_bits.h"
27 #include "put_bits.h"
28 
29 #define FRAME_SLOTS 8
30 
31 typedef struct VP9RawReorderFrame {
35 
36  int64_t pts;
37  int64_t sequence;
38  unsigned int slots;
39 
40  unsigned int profile;
41 
42  unsigned int show_existing_frame;
43  unsigned int frame_to_show;
44 
45  unsigned int frame_type;
46  unsigned int show_frame;
47  unsigned int refresh_frame_flags;
49 
50 typedef struct VP9RawReorderContext {
51  int64_t sequence;
55 
57 {
58  if (*frame)
59  av_packet_free(&(*frame)->packet);
60  av_freep(frame);
61 }
62 
64 {
65  if (ctx->slot[s]) {
66  ctx->slot[s]->slots &= ~(1 << s);
67  if (ctx->slot[s]->slots == 0)
69  else
70  ctx->slot[s] = NULL;
71  }
72 }
73 
75 {
76  GetBitContext bc;
77  int err;
78 
79  unsigned int frame_marker;
80  unsigned int profile_low_bit, profile_high_bit, reserved_zero;
81  unsigned int error_resilient_mode;
82  unsigned int frame_sync_code;
83 
84  err = init_get_bits(&bc, frame->packet->data, 8 * frame->packet->size);
85  if (err)
86  return err;
87 
88  frame_marker = get_bits(&bc, 2);
89  if (frame_marker != 2) {
90  av_log(bsf, AV_LOG_ERROR, "Invalid frame marker: %u.\n",
91  frame_marker);
92  return AVERROR_INVALIDDATA;
93  }
94 
95  profile_low_bit = get_bits1(&bc);
96  profile_high_bit = get_bits1(&bc);
97  frame->profile = (profile_high_bit << 1) | profile_low_bit;
98  if (frame->profile == 3) {
99  reserved_zero = get_bits1(&bc);
100  if (reserved_zero != 0) {
101  av_log(bsf, AV_LOG_ERROR, "Profile reserved_zero bit set: "
102  "unsupported profile or invalid bitstream.\n");
103  return AVERROR_INVALIDDATA;
104  }
105  }
106 
107  frame->show_existing_frame = get_bits1(&bc);
108  if (frame->show_existing_frame) {
109  frame->frame_to_show = get_bits(&bc, 3);
110  return 0;
111  }
112 
113  frame->frame_type = get_bits1(&bc);
114  frame->show_frame = get_bits1(&bc);
115  error_resilient_mode = get_bits1(&bc);
116 
117  if (frame->frame_type == 0) {
118  frame_sync_code = get_bits(&bc, 24);
119  if (frame_sync_code != 0x498342) {
120  av_log(bsf, AV_LOG_ERROR, "Invalid frame sync code: %06x.\n",
121  frame_sync_code);
122  return AVERROR_INVALIDDATA;
123  }
124  frame->refresh_frame_flags = 0xff;
125  } else {
126  unsigned int intra_only;
127 
128  if (frame->show_frame == 0)
129  intra_only = get_bits1(&bc);
130  else
131  intra_only = 0;
132  if (error_resilient_mode == 0) {
133  // reset_frame_context
134  skip_bits(&bc, 2);
135  }
136  if (intra_only) {
137  frame_sync_code = get_bits(&bc, 24);
138  if (frame_sync_code != 0x498342) {
139  av_log(bsf, AV_LOG_ERROR, "Invalid frame sync code: "
140  "%06x.\n", frame_sync_code);
141  return AVERROR_INVALIDDATA;
142  }
143  if (frame->profile > 0) {
144  unsigned int color_space;
145  if (frame->profile >= 2) {
146  // ten_or_twelve_bit
147  skip_bits(&bc, 1);
148  }
149  color_space = get_bits(&bc, 3);
150  if (color_space != 7 /* CS_RGB */) {
151  // color_range
152  skip_bits(&bc, 1);
153  if (frame->profile == 1 || frame->profile == 3) {
154  // subsampling
155  skip_bits(&bc, 3);
156  }
157  } else {
158  if (frame->profile == 1 || frame->profile == 3)
159  skip_bits(&bc, 1);
160  }
161  }
162  frame->refresh_frame_flags = get_bits(&bc, 8);
163  } else {
164  frame->refresh_frame_flags = get_bits(&bc, 8);
165  }
166  }
167 
168  return 0;
169 }
170 
172  AVPacket *out,
173  VP9RawReorderFrame *last_frame)
174 {
176  VP9RawReorderFrame *next_output = last_frame,
177  *next_display = last_frame, *frame;
178  int s, err;
179 
180  for (s = 0; s < FRAME_SLOTS; s++) {
181  frame = ctx->slot[s];
182  if (!frame)
183  continue;
184  if (frame->needs_output && (!next_output ||
185  frame->sequence < next_output->sequence))
186  next_output = frame;
187  if (frame->needs_display && (!next_display ||
188  frame->pts < next_display->pts))
189  next_display = frame;
190  }
191 
192  if (!next_output && !next_display)
193  return AVERROR_EOF;
194 
195  if (!next_display || (next_output &&
196  next_output->sequence < next_display->sequence))
197  frame = next_output;
198  else
199  frame = next_display;
200 
201  if (frame->needs_output && frame->needs_display &&
202  next_output == next_display) {
203  av_log(bsf, AV_LOG_DEBUG, "Output and display frame "
204  "%"PRId64" (%"PRId64") in order.\n",
205  frame->sequence, frame->pts);
206 
207  av_packet_move_ref(out, frame->packet);
208 
209  frame->needs_output = frame->needs_display = 0;
210  } else if (frame->needs_output) {
211  if (frame->needs_display) {
212  av_log(bsf, AV_LOG_DEBUG, "Output frame %"PRId64" "
213  "(%"PRId64") for later display.\n",
214  frame->sequence, frame->pts);
215  } else {
216  av_log(bsf, AV_LOG_DEBUG, "Output unshown frame "
217  "%"PRId64" (%"PRId64") to keep order.\n",
218  frame->sequence, frame->pts);
219  }
220 
221  av_packet_move_ref(out, frame->packet);
222  out->pts = out->dts;
223 
224  frame->needs_output = 0;
225  } else {
226  PutBitContext pb;
227 
228  av_assert0(!frame->needs_output && frame->needs_display);
229 
230  if (frame->slots == 0) {
231  av_log(bsf, AV_LOG_ERROR, "Attempting to display frame "
232  "which is no longer available?\n");
233  frame->needs_display = 0;
234  return AVERROR_INVALIDDATA;
235  }
236 
237  s = ff_ctz(frame->slots);
238  av_assert0(s < FRAME_SLOTS);
239 
240  av_log(bsf, AV_LOG_DEBUG, "Display frame %"PRId64" "
241  "(%"PRId64") from slot %d.\n",
242  frame->sequence, frame->pts, s);
243 
244  err = av_new_packet(out, 2);
245  if (err < 0)
246  return err;
247 
248  init_put_bits(&pb, out->data, 2);
249 
250  // frame_marker
251  put_bits(&pb, 2, 2);
252  // profile_low_bit
253  put_bits(&pb, 1, frame->profile & 1);
254  // profile_high_bit
255  put_bits(&pb, 1, (frame->profile >> 1) & 1);
256  if (frame->profile == 3) {
257  // reserved_zero
258  put_bits(&pb, 1, 0);
259  }
260  // show_existing_frame
261  put_bits(&pb, 1, 1);
262  // frame_to_show_map_idx
263  put_bits(&pb, 3, s);
264 
265  while (put_bits_count(&pb) < 16)
266  put_bits(&pb, 1, 0);
267 
268  flush_put_bits(&pb);
269  out->pts = out->dts = frame->pts;
270 
271  frame->needs_display = 0;
272  }
273 
274  return 0;
275 }
276 
278 {
281  AVPacket *in;
282  int err, s;
283 
284  if (ctx->next_frame) {
285  frame = ctx->next_frame;
286 
287  } else {
288  err = ff_bsf_get_packet(bsf, &in);
289  if (err < 0) {
290  if (err == AVERROR_EOF)
291  return vp9_raw_reorder_make_output(bsf, out, NULL);
292  return err;
293  }
294 
295  if (in->data[in->size - 1] & 0xe0 == 0xc0) {
296  av_log(bsf, AV_LOG_ERROR, "Input in superframes is not "
297  "supported.\n");
298  av_packet_free(&in);
299  return AVERROR(ENOSYS);
300  }
301 
302  frame = av_mallocz(sizeof(*frame));
303  if (!frame) {
304  av_packet_free(&in);
305  return AVERROR(ENOMEM);
306  }
307 
308  frame->packet = in;
309  frame->pts = in->pts;
310  frame->sequence = ++ctx->sequence;
311  err = vp9_raw_reorder_frame_parse(bsf, frame);
312  if (err) {
313  av_log(bsf, AV_LOG_ERROR, "Failed to parse input "
314  "frame: %d.\n", err);
315  goto fail;
316  }
317 
318  frame->needs_output = 1;
319  frame->needs_display = frame->pts != AV_NOPTS_VALUE;
320 
321  if (frame->show_existing_frame)
322  av_log(bsf, AV_LOG_DEBUG, "Show frame %"PRId64" "
323  "(%"PRId64"): show %u.\n", frame->sequence,
324  frame->pts, frame->frame_to_show);
325  else
326  av_log(bsf, AV_LOG_DEBUG, "New frame %"PRId64" "
327  "(%"PRId64"): type %u show %u refresh %02x.\n",
328  frame->sequence, frame->pts, frame->frame_type,
329  frame->show_frame, frame->refresh_frame_flags);
330 
331  ctx->next_frame = frame;
332  }
333 
334  for (s = 0; s < FRAME_SLOTS; s++) {
335  if (!(frame->refresh_frame_flags & (1 << s)))
336  continue;
337  if (ctx->slot[s] && ctx->slot[s]->needs_display &&
338  ctx->slot[s]->slots == (1 << s)) {
339  // We are overwriting this slot, which is last reference
340  // to the frame previously present in it. In order to be
341  // a valid stream, that frame must already have been
342  // displayed before the pts of the current frame.
343  err = vp9_raw_reorder_make_output(bsf, out, ctx->slot[s]);
344  if (err < 0) {
345  av_log(bsf, AV_LOG_ERROR, "Failed to create "
346  "output overwriting slot %d: %d.\n",
347  s, err);
348  // Clear the slot anyway, so we don't end up
349  // in an infinite loop.
351  return AVERROR_INVALIDDATA;
352  }
353  return 0;
354  }
356  }
357 
358  for (s = 0; s < FRAME_SLOTS; s++) {
359  if (!(frame->refresh_frame_flags & (1 << s)))
360  continue;
361  ctx->slot[s] = frame;
362  }
363  frame->slots = frame->refresh_frame_flags;
364 
365  if (!frame->refresh_frame_flags) {
366  err = vp9_raw_reorder_make_output(bsf, out, frame);
367  if (err < 0) {
368  av_log(bsf, AV_LOG_ERROR, "Failed to create output "
369  "for transient frame.\n");
370  ctx->next_frame = NULL;
371  return AVERROR_INVALIDDATA;
372  }
373  if (!frame->needs_display) {
375  ctx->next_frame = NULL;
376  }
377  return 0;
378  }
379 
380  ctx->next_frame = NULL;
381  return AVERROR(EAGAIN);
382 
383 fail:
385  return err;
386 }
387 
389 {
391  int s;
392 
393  for (s = 0; s < FRAME_SLOTS; s++)
395 }
396 
397 static const enum AVCodecID vp9_raw_reorder_codec_ids[] = {
399 };
400 
402  .name = "vp9_raw_reorder",
403  .priv_data_size = sizeof(VP9RawReorderContext),
404  .close = &vp9_raw_reorder_close,
407 };
#define NULL
Definition: coverity.c:32
#define ff_ctz
Definition: intmath.h:106
const char * s
Definition: avisynth_c.h:768
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
static void put_bits(Jpeg2000EncoderContext *s, int val, int n)
put n times val bit
Definition: j2kenc.c:207
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:269
Memory handling functions.
The bitstream filter state.
Definition: avcodec.h:5687
int size
Definition: avcodec.h:1431
unsigned int frame_to_show
void * priv_data
Opaque filter-specific private data.
Definition: avcodec.h:5708
static int vp9_raw_reorder_filter(AVBSFContext *bsf, AVPacket *out)
static void vp9_raw_reorder_close(AVBSFContext *bsf)
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
static void filter(int16_t *output, ptrdiff_t out_stride, int16_t *low, ptrdiff_t low_stride, int16_t *high, ptrdiff_t high_stride, int len, int clip)
Definition: cfhd.c:114
static int vp9_raw_reorder_frame_parse(AVBSFContext *bsf, VP9RawReorderFrame *frame)
void av_packet_free(AVPacket **pkt)
Free the packet, if the packet is reference counted, it will be unreferenced first.
Definition: avpacket.c:62
const AVBitStreamFilter ff_vp9_raw_reorder_bsf
AVOptions.
static AVFrame * frame
const char * name
Definition: avcodec.h:5737
uint8_t * data
Definition: avcodec.h:1430
void av_packet_move_ref(AVPacket *dst, AVPacket *src)
Move every field in src to dst and reset src.
Definition: avpacket.c:647
#define AVERROR_EOF
End of file.
Definition: error.h:55
bitstream reader API header.
#define av_log(a,...)
int av_new_packet(AVPacket *pkt, int size)
Allocate the payload of a packet and initialize its fields with default values.
Definition: avpacket.c:86
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: avcodec.h:215
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
#define AVERROR(e)
Definition: error.h:43
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
simple assert() macros that are a bit more flexible than ISO C assert().
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:236
VP9RawReorderFrame * next_frame
#define fail()
Definition: checkasm.h:116
static int put_bits_count(PutBitContext *s)
Definition: put_bits.h:85
AVFormatContext * ctx
Definition: movenc.c:48
#define FRAME_SLOTS
unsigned int refresh_frame_flags
static int intra_only
Definition: ffmpeg_opt.c:115
static unsigned int get_bits1(GetBitContext *s)
Definition: get_bits.h:321
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) #define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac) { } void ff_audio_convert_free(AudioConvert **ac) { if(! *ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);} AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map) { AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method !=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2) { ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc) { av_free(ac);return NULL;} return ac;} in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar) { ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar ? ac->channels :1;} else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;} int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in) { int use_generic=1;int len=in->nb_samples;int p;if(ac->dc) { av_log(ac->avr, AV_LOG_TRACE, "%d samples - audio_convert: %s to %s (dithered)\", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> in
static void vp9_raw_reorder_clear_slot(VP9RawReorderContext *ctx, int s)
static void skip_bits(GetBitContext *s, int n)
Definition: get_bits.h:314
VP9RawReorderFrame * slot[FRAME_SLOTS]
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition: get_bits.h:433
static void flush_put_bits(PutBitContext *s)
Pad the end of the output stream with zeros.
Definition: put_bits.h:101
static enum AVCodecID codec_ids[]
int ff_bsf_get_packet(AVBSFContext *ctx, AVPacket **pkt)
Called by the bitstream filters to get the next packet for filtering.
Definition: bsf.c:206
static void init_put_bits(PutBitContext *s, uint8_t *buffer, int buffer_size)
Initialize the PutBitContext s.
Definition: put_bits.h:48
static enum AVCodecID vp9_raw_reorder_codec_ids[]
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed...
Definition: avcodec.h:1429
static void vp9_raw_reorder_frame_free(VP9RawReorderFrame **frame)
FILE * out
Definition: movenc.c:54
#define av_freep(p)
static int vp9_raw_reorder_make_output(AVBSFContext *bsf, AVPacket *out, VP9RawReorderFrame *last_frame)
This structure stores compressed data.
Definition: avcodec.h:1407
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: avcodec.h:1423
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
unsigned int show_existing_frame
bitstream writer API