FFmpeg
ohdec.c
Go to the documentation of this file.
1 /*
2  * This file is part of FFmpeg.
3  *
4  * Copyright (c) 2025 Zhao Zhili <quinkblack@foxmail.com>
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include "config_components.h"
22 
23 #include <stdbool.h>
24 #include <multimedia/player_framework/native_avcapability.h>
25 #include <multimedia/player_framework/native_avcodec_videodecoder.h>
26 
27 #include "libavutil/fifo.h"
28 #include "libavutil/hwcontext_oh.h"
29 #include "libavutil/imgutils.h"
30 #include "libavutil/mem.h"
31 #include "libavutil/opt.h"
32 #include "libavutil/refstruct.h"
33 #include "libavutil/thread.h"
34 
35 #include "avcodec.h"
36 #include "codec_internal.h"
37 #include "decode.h"
38 #include "hwconfig.h"
39 #include "ohcodec.h"
40 #include "pthread_internal.h"
41 
42 typedef struct OHCodecDecContext {
44  OH_AVCodec *dec;
45  /* A RefStruct reference backing dec. Each hardware frame has a reference count to
46  * dec. dec will be destroyed only after oh_decode_close and all hardware
47  * frames have been released.
48  */
49  OH_AVCodec **dec_ref;
50 
54 
58 
60 
62  bool eof_sent;
63 
66  int width;
67  int height;
68  int stride;
70  OH_AVPixelFormat pix_fmt;
71 
72  char *name;
73  int allow_sw;
74  unsigned mutex_cond_cnt;
76 
77 #define OFFSET(x) offsetof(OHCodecDecContext, x)
78 DEFINE_OFFSET_ARRAY(OHCodecDecContext, mutex_cond, mutex_cond_cnt,
79  (OFFSET(input_mutex), OFFSET(output_mutex)),
80  (OFFSET(input_cond), OFFSET(output_cond)));
81 
82 typedef struct OHCodecBuffer {
83  uint32_t index;
84  OH_AVBuffer *buffer;
85  OH_AVCodec **dec_ref; ///< RefStruct reference
87 
88 static void oh_decode_release(AVRefStructOpaque unused, void *obj)
89 {
90  OH_AVCodec **decp = obj;
91  OH_AVErrCode err = OH_VideoDecoder_Destroy(*decp);
92  if (err == AV_ERR_OK)
93  av_log(NULL, AV_LOG_DEBUG, "Destroy decoder success\n");
94  else
95  av_log(NULL, AV_LOG_ERROR, "Destroy decoder failed, %d, %s\n",
96  err, av_err2str(ff_oh_err_to_ff_err(err)));
97 }
98 
100 {
101  const char *name = s->name;
102 
103  if (!name) {
104  const char *mime = ff_oh_mime(avctx->codec_id, avctx);
105  if (!mime)
106  return AVERROR_BUG;
107  OH_AVCapability *cap = OH_AVCodec_GetCapabilityByCategory(mime, false, HARDWARE);
108  if (!cap) {
109  if (!s->allow_sw) {
110  av_log(avctx, AV_LOG_ERROR, "Failed to get hardware codec %s\n", mime);
111  return AVERROR_EXTERNAL;
112  }
113  av_log(avctx, AV_LOG_WARNING,
114  "Failed to get hardware codec %s, try software backend\n", mime);
115  cap = OH_AVCodec_GetCapabilityByCategory(mime, false, SOFTWARE);
116  if (!cap) {
117  av_log(avctx, AV_LOG_ERROR, "Failed to get software codec %s\n", mime);
118  return AVERROR_EXTERNAL;
119  }
120  }
121  name = OH_AVCapability_GetName(cap);
122  if (!name)
123  return AVERROR_EXTERNAL;
124  }
125 
126  s->dec = OH_VideoDecoder_CreateByName(name);
127  if (!s->dec) {
128  av_log(avctx, AV_LOG_ERROR, "Create decoder with name %s failed\n", name);
129  return AVERROR_EXTERNAL;
130  }
131  av_log(avctx, AV_LOG_DEBUG, "Create decoder %s success\n", name);
132 
133  s->dec_ref = av_refstruct_alloc_ext(sizeof(*s->dec_ref), 0, NULL, oh_decode_release);
134  if (!s->dec_ref) {
135  oh_decode_release((AVRefStructOpaque){.nc = NULL }, &s->dec);
136  s->dec = NULL;
137  return AVERROR(ENOMEM);
138  }
139  *s->dec_ref = s->dec;
140 
141  return 0;
142 }
143 
145 {
146  int ret;
147  OHNativeWindow *window = NULL;
148 
149  if (avctx->hw_device_ctx) {
150  AVHWDeviceContext *device_ctx = (AVHWDeviceContext*)(avctx->hw_device_ctx->data);
151  if (device_ctx->type == AV_HWDEVICE_TYPE_OHCODEC) {
152  AVOHCodecDeviceContext *dev = device_ctx->hwctx;
153  window = dev->native_window;
154  s->output_to_window = true;
155  } else {
156  av_log(avctx, AV_LOG_WARNING, "Ignore invalid hw device type %s\n",
157  av_hwdevice_get_type_name(device_ctx->type));
158  }
159  }
160 
161  if (avctx->width <= 0 || avctx->height <= 0) {
162  av_log(avctx, AV_LOG_ERROR,
163  "Invalid width/height (%dx%d), width and height are mandatory for ohcodec\n",
164  avctx->width, avctx->height);
165  return AVERROR(EINVAL);
166  }
167 
168  OH_AVFormat *format = OH_AVFormat_Create();
169  if (!format)
170  return AVERROR(ENOMEM);
171 
172  OH_AVFormat_SetIntValue(format, OH_MD_KEY_WIDTH, avctx->width);
173  OH_AVFormat_SetIntValue(format, OH_MD_KEY_HEIGHT, avctx->height);
174  if (!s->output_to_window)
175  OH_AVFormat_SetIntValue(format, OH_MD_KEY_PIXEL_FORMAT,
176  AV_PIXEL_FORMAT_NV12);
177  else
178  OH_AVFormat_SetIntValue(format, OH_MD_KEY_PIXEL_FORMAT,
179  AV_PIXEL_FORMAT_SURFACE_FORMAT);
180  OH_AVErrCode err = OH_VideoDecoder_Configure(s->dec, format);
181  OH_AVFormat_Destroy(format);
182  if (err != AV_ERR_OK) {
183  ret = ff_oh_err_to_ff_err(err);
184  av_log(avctx, AV_LOG_ERROR, "Decoder configure failed, %d, %s\n",
185  err, av_err2str(ret));
186  return ret;
187  }
188 
189  if (s->output_to_window) {
190  err = OH_VideoDecoder_SetSurface(s->dec, window);
191  if (err != AV_ERR_OK) {
192  ret = ff_oh_err_to_ff_err(err);
193  av_log(avctx, AV_LOG_ERROR, "Set surface failed, %d, %s\n",
194  err, av_err2str(ret));
195  return ret;
196  }
197  }
198 
199  return 0;
200 }
201 
202 static void oh_decode_on_err(OH_AVCodec *codec, int32_t err, void *userdata)
203 {
204  AVCodecContext *avctx = userdata;
205  OHCodecDecContext *s = avctx->priv_data;
206 
207  // Careful on the lock order.
208  // Always lock input first.
209  ff_mutex_lock(&s->input_mutex);
210  ff_mutex_lock(&s->output_mutex);
211  s->decode_status = ff_oh_err_to_ff_err(err);
212  ff_mutex_unlock(&s->output_mutex);
213  ff_mutex_unlock(&s->input_mutex);
214 
215  ff_cond_signal(&s->output_cond);
216  ff_cond_signal(&s->input_cond);
217 }
218 
219 static void oh_decode_on_stream_changed(OH_AVCodec *codec, OH_AVFormat *format,
220  void *userdata)
221 {
222  AVCodecContext *avctx = userdata;
223  OHCodecDecContext *s = avctx->priv_data;
224  int32_t n;
225  double d;
226 
227  if (!OH_AVFormat_GetIntValue(format, OH_MD_KEY_VIDEO_PIC_WIDTH, &s->width) ||
228  !OH_AVFormat_GetIntValue(format, OH_MD_KEY_VIDEO_PIC_HEIGHT, &s->height) ||
229  !OH_AVFormat_GetIntValue(format, OH_MD_KEY_VIDEO_STRIDE, &s->stride) ||
230  !OH_AVFormat_GetIntValue(format, OH_MD_KEY_VIDEO_SLICE_HEIGHT,
231  &s->slice_height)) {
232  av_log(avctx, AV_LOG_ERROR, "Get dimension info from format failed\n");
233  goto out;
234  }
235 
236  if (ff_set_dimensions(avctx, s->width, s->height) < 0)
237  goto out;
238 
239  if (s->stride <= 0 || s->slice_height <= 0) {
240  av_log(avctx, AV_LOG_ERROR,
241  "Buffer stride (%d) or slice height (%d) is invalid\n",
242  s->stride, s->slice_height);
243  goto out;
244  }
245 
246  if (OH_AVFormat_GetIntValue(format, OH_MD_KEY_PIXEL_FORMAT, &n)) {
247  s->pix_fmt = n;
248  /* When use output_to_window, the returned format is the memory
249  * layout of hardware frame, not AV_PIXEL_FORMAT_SURFACE_FORMAT as
250  * expected.
251  */
252  if (s->output_to_window)
253  avctx->pix_fmt = AV_PIX_FMT_OHCODEC;
254  else
255  avctx->pix_fmt = ff_oh_pix_to_ff_pix(s->pix_fmt);
256  // Check whether this pixel format is supported
257  if (avctx->pix_fmt == AV_PIX_FMT_NONE) {
258  av_log(avctx, AV_LOG_ERROR, "Unsupported OH_AVPixelFormat %d\n",
259  n);
260  goto out;
261  }
262  } else {
263  av_log(avctx, AV_LOG_ERROR, "Failed to get pixel format\n");
264  goto out;
265  }
266 
267  if (OH_AVFormat_GetIntValue(format,
268  OH_MD_KEY_MATRIX_COEFFICIENTS,
269  &n))
270  avctx->colorspace = n;
271  if (OH_AVFormat_GetIntValue(format,
272  OH_MD_KEY_COLOR_PRIMARIES,
273  &n))
274  avctx->color_primaries = n;
275  if (OH_AVFormat_GetIntValue(format,
276  OH_MD_KEY_TRANSFER_CHARACTERISTICS,
277  &n))
278  avctx->color_trc = n;
279  if (OH_AVFormat_GetIntValue(format,
280  OH_MD_KEY_RANGE_FLAG,
281  &n))
283 
284  if (OH_AVFormat_GetDoubleValue(format, OH_MD_KEY_VIDEO_SAR, &d)) {
285  AVRational sar = av_d2q(d, 4096 * 4);
286  ff_set_sar(avctx, sar);
287  }
288 
289  s->got_stream_info = true;
290 
291  return;
292 out:
293  av_log(avctx, AV_LOG_ERROR, "Invalid format from decoder: %s\n",
294  OH_AVFormat_DumpInfo(format));
295  oh_decode_on_err(codec, AV_ERR_UNKNOWN, userdata);
296 }
297 
298 static void oh_decode_on_need_input(OH_AVCodec *codec, uint32_t index,
299  OH_AVBuffer *buffer, void *userdata)
300 {
301  AVCodecContext *avctx = userdata;
302  OHCodecDecContext *s = avctx->priv_data;
303  OHBufferQueueItem item = {
304  index, buffer,
305  };
306 
307  ff_mutex_lock(&s->input_mutex);
308  int ret = av_fifo_write(s->input_queue, &item, 1);
309  if (ret >= 0)
310  ff_cond_signal(&s->input_cond);
311  ff_mutex_unlock(&s->input_mutex);
312 
313  if (ret < 0)
314  oh_decode_on_err(codec, AV_ERR_NO_MEMORY, userdata);
315 }
316 
317 static void oh_decode_on_output(OH_AVCodec *codec, uint32_t index,
318  OH_AVBuffer *buffer, void *userdata)
319 {
320  AVCodecContext *avctx = userdata;
321  OHCodecDecContext *s = avctx->priv_data;
322  OHBufferQueueItem item = {
323  index, buffer,
324  };
325 
326  ff_mutex_lock(&s->output_mutex);
327  int ret = av_fifo_write(s->output_queue, &item, 1);
328  if (ret >= 0)
329  ff_cond_signal(&s->output_cond);
330  ff_mutex_unlock(&s->output_mutex);
331 
332  if (ret < 0)
333  oh_decode_on_err(codec, AV_ERR_NO_MEMORY, userdata);
334 }
335 
337 {
338  int ret;
339  OH_AVErrCode err;
340  OH_AVCodecCallback cb = {
341  .onError = oh_decode_on_err,
342  .onStreamChanged = oh_decode_on_stream_changed,
343  .onNeedInputBuffer = oh_decode_on_need_input,
344  .onNewOutputBuffer = oh_decode_on_output,
345  };
346 
347  err = OH_VideoDecoder_RegisterCallback(s->dec, cb, avctx);
348  if (err != AV_ERR_OK) {
349  ret = ff_oh_err_to_ff_err(err);
350  av_log(avctx, AV_LOG_ERROR, "Register callback failed, %d, %s\n",
351  err, av_err2str(ret));
352  return ret;
353  }
354  err = OH_VideoDecoder_Prepare(s->dec);
355  if (err != AV_ERR_OK) {
356  ret = ff_oh_err_to_ff_err(err);
357  av_log(avctx, AV_LOG_ERROR, "Prepare failed, %d, %s\n",
358  err, av_err2str(ret));
359  return ret;
360  }
361  err = OH_VideoDecoder_Start(s->dec);
362  if (err != AV_ERR_OK) {
363  ret = ff_oh_err_to_ff_err(err);
364  av_log(avctx, AV_LOG_ERROR, "Start failed, %d, %s\n",
365  err, av_err2str(ret));
366  return ret;
367  }
368 
369  return 0;
370 }
371 
373 {
374  OHCodecDecContext *s = avctx->priv_data;
375 
376  // Initialize these fields first, so oh_decode_close can destroy them safely
377  int ret = ff_pthread_init(s, mutex_cond_offsets);
378  if (ret < 0)
379  return ret;
380 
381  ret = oh_decode_create(s, avctx);
382  if (ret < 0)
383  return ret;
384  ret = oh_decode_set_format(s, avctx);
385  if (ret < 0)
386  return ret;
387 
388  size_t fifo_size = 16;
389  s->input_queue = av_fifo_alloc2(fifo_size, sizeof(OHBufferQueueItem),
391  s->output_queue = av_fifo_alloc2(fifo_size, sizeof(OHBufferQueueItem),
393  if (!s->input_queue || !s->output_queue)
394  return AVERROR(ENOMEM);
395 
396  ret = oh_decode_start(s, avctx);
397  if (ret < 0)
398  return ret;
399 
400  return 0;
401 }
402 
404 {
405  OHCodecDecContext *s = avctx->priv_data;
406 
407  if (s->dec) {
408  /* Stop but don't destroy dec directly, to keep hardware frames on
409  * the fly valid.
410  */
411  OH_AVErrCode err = OH_VideoDecoder_Stop(s->dec);
412  if (err == AV_ERR_OK)
413  av_log(avctx, AV_LOG_DEBUG, "Stop decoder success\n");
414  else
415  av_log(avctx, AV_LOG_ERROR, "Stop decoder failed, %d, %s\n",
416  err, av_err2str(ff_oh_err_to_ff_err(err)));
417  s->dec = NULL;
418  av_refstruct_unref(&s->dec_ref);
419  }
420 
421  av_packet_unref(&s->pkt);
422 
423  av_fifo_freep2(&s->input_queue);
424 
425  av_fifo_freep2(&s->output_queue);
426 
427  ff_pthread_free(s, mutex_cond_offsets);
428 
429  return 0;
430 }
431 
432 static void oh_buffer_release(void *opaque, uint8_t *data)
433 {
434  if (!opaque)
435  return;
436 
437  OHCodecBuffer *buffer = opaque;
438 
439  if (buffer->buffer) {
440  OH_AVCodec *dec = *buffer->dec_ref;
441  OH_AVCodecBufferAttr attr;
442  OH_AVErrCode err = OH_AVBuffer_GetBufferAttr(buffer->buffer, &attr);
443  if (err == AV_ERR_OK && !(attr.flags & AVCODEC_BUFFER_FLAGS_DISCARD))
444  OH_VideoDecoder_RenderOutputBuffer(dec, buffer->index);
445  else
446  OH_VideoDecoder_FreeOutputBuffer(dec, buffer->index);
447  }
448 
449  av_refstruct_unref(&buffer->dec_ref);
450  av_free(buffer);
451 }
452 
455  const OH_AVCodecBufferAttr *attr)
456 {
457  OHCodecDecContext *s = avctx->priv_data;
458 
459  frame->width = s->width;
460  frame->height = s->height;
461  int ret = ff_decode_frame_props(avctx, frame);
462  if (ret < 0)
463  return ret;
464 
465  frame->format = AV_PIX_FMT_OHCODEC;
466  OHCodecBuffer *buffer = av_mallocz(sizeof(*buffer));
467  if (!buffer)
468  return AVERROR(ENOMEM);
469 
470  buffer->dec_ref = av_refstruct_ref(s->dec_ref);
471 
472  buffer->index = output->index;
473  buffer->buffer = output->buffer;
474  frame->buf[0] = av_buffer_create((uint8_t *)buffer->buffer, 1,
477  if (!frame->buf[0]) {
479  return AVERROR(ENOMEM);
480  }
481  // Point to OH_AVBuffer
482  frame->data[3] = frame->buf[0]->data;
483  frame->pts = av_rescale_q(attr->pts, AV_TIME_BASE_Q, avctx->pkt_timebase);
484  frame->pkt_dts = AV_NOPTS_VALUE;
485 
486  return 0;
487 }
488 
491  const OH_AVCodecBufferAttr *attr)
492 {
493  OHCodecDecContext *s = avctx->priv_data;
494 
495  frame->format = avctx->pix_fmt;
496  frame->width = s->width;
497  frame->height = s->height;
498  int ret = ff_get_buffer(avctx, frame, 0);
499  if (ret < 0)
500  return ret;
501 
502  frame->pts = av_rescale_q(attr->pts, AV_TIME_BASE_Q, avctx->pkt_timebase);
503  frame->pkt_dts = AV_NOPTS_VALUE;
504 
505  uint8_t *p = OH_AVBuffer_GetAddr(output->buffer);
506  if (!p) {
507  av_log(avctx, AV_LOG_ERROR, "Failed to get output buffer addr\n");
508  return AVERROR_EXTERNAL;
509  }
510 
511  uint8_t *src[4] = {0};
512  int src_linesizes[4] = {0};
513 
514  ret = av_image_fill_linesizes(src_linesizes, frame->format, s->stride);
515  if (ret < 0)
516  return ret;
517  ret = av_image_fill_pointers(src, frame->format, s->slice_height, p,
518  src_linesizes);
519  if (ret < 0)
520  return ret;
521  av_image_copy2(frame->data, frame->linesize, src, src_linesizes,
522  frame->format, frame->width, frame->height);
523 
524  OH_AVErrCode err = OH_VideoDecoder_FreeOutputBuffer(s->dec, output->index);
525  if (err != AV_ERR_OK) {
526  ret = ff_oh_err_to_ff_err(err);
527  av_log(avctx, AV_LOG_ERROR, "FreeOutputBuffer failed, %d, %s\n", err,
528  av_err2str(ret));
529  return ret;
530  }
531 
532  return 0;
533 }
534 
537 {
538  OHCodecDecContext *s = avctx->priv_data;
539  OH_AVCodecBufferAttr attr;
540 
541  OH_AVErrCode err = OH_AVBuffer_GetBufferAttr(output->buffer, &attr);
542  if (err != AV_ERR_OK)
543  return ff_oh_err_to_ff_err(err);
544 
545  if (attr.flags & AVCODEC_BUFFER_FLAGS_EOS) {
546  av_log(avctx, AV_LOG_DEBUG, "Buffer flag eos\n");
547  OH_VideoDecoder_FreeOutputBuffer(s->dec, output->index);
548  return AVERROR_EOF;
549  }
550 
551  if (!s->got_stream_info) {
552  // This shouldn't happen, add a warning message.
553  av_log(avctx, AV_LOG_WARNING,
554  "decoder didn't notify stream info, try get format explicitly\n");
555 
556  OH_AVFormat *format = OH_VideoDecoder_GetOutputDescription(s->dec);
557  if (!format) {
558  av_log(avctx, AV_LOG_ERROR, "GetOutputDescription failed\n");
559  return AVERROR_EXTERNAL;
560  }
561 
562  oh_decode_on_stream_changed(s->dec, format, avctx);
563  OH_AVFormat_Destroy(format);
564  if (!s->got_stream_info)
565  return AVERROR_EXTERNAL;
566  }
567 
568  if (s->output_to_window)
569  return oh_decode_wrap_hw_buffer(avctx, frame, output, &attr);
570  return oh_decode_wrap_sw_buffer(avctx, frame, output, &attr);
571 }
572 
574 {
575  OHCodecDecContext *s = avctx->priv_data;
576  OH_AVErrCode err;
577  int ret;
578 
579  if (!s->pkt.size && !s->eof_sent) {
580  OH_AVCodecBufferAttr attr = {
581  .flags = AVCODEC_BUFFER_FLAGS_EOS,
582  };
583  err = OH_AVBuffer_SetBufferAttr(input->buffer, &attr);
584  if (err != AV_ERR_OK)
585  return ff_oh_err_to_ff_err(err);
586  err = OH_VideoDecoder_PushInputBuffer(s->dec, input->index);
587  if (err != AV_ERR_OK)
588  return ff_oh_err_to_ff_err(err);
589  s->eof_sent = true;
590  return 0;
591  }
592 
593  uint8_t *p = OH_AVBuffer_GetAddr(input->buffer);
594  int32_t n = OH_AVBuffer_GetCapacity(input->buffer);
595  if (!p || n <= 0) {
596  av_log(avctx, AV_LOG_ERROR,
597  "Failed to get buffer addr (%p) or capacity (%d)\n",
598  p, n);
599  return AVERROR_EXTERNAL;
600  }
601  n = FFMIN(s->pkt.size, n);
602  memcpy(p, s->pkt.data, n);
603 
604  OH_AVCodecBufferAttr attr = {
605  .size = n,
606  .offset = 0,
607  .pts = av_rescale_q(s->pkt.pts, avctx->pkt_timebase,
609  .flags = (s->pkt.flags & AV_PKT_FLAG_KEY)
610  ? AVCODEC_BUFFER_FLAGS_SYNC_FRAME : 0,
611  };
612 
613  err = OH_AVBuffer_SetBufferAttr(input->buffer, &attr);
614  if (err != AV_ERR_OK) {
615  ret = ff_oh_err_to_ff_err(err);
616  return ret;
617  }
618  err = OH_VideoDecoder_PushInputBuffer(s->dec, input->index);
619  if (err != AV_ERR_OK) {
620  ret = ff_oh_err_to_ff_err(err);
621  av_log(avctx, AV_LOG_ERROR, "Push input buffer failed, %d, %s\n",
622  err, av_err2str(ret));
623  return ret;
624  }
625 
626  if (n < s->pkt.size) {
627  s->pkt.size -= n;
628  s->pkt.data += n;
629  } else {
630  av_packet_unref(&s->pkt);
631  }
632 
633  return 0;
634 }
635 
637 {
638  OHCodecDecContext *s = avctx->priv_data;
639 
640  while (1) {
642  int ret;
643 
644  // Try get output
645  ff_mutex_lock(&s->output_mutex);
646  while (!s->decode_status) {
647  if (av_fifo_read(s->output_queue, &buffer, 1) >= 0)
648  break;
649  // Only wait after send EOF
650  if (s->eof_sent && !s->decode_status)
651  ff_cond_wait(&s->output_cond, &s->output_mutex);
652  else
653  break;
654  }
655 
656  ret = s->decode_status;
657  ff_mutex_unlock(&s->output_mutex);
658 
659  // Got a frame
660  if (buffer.buffer)
661  return oh_decode_output_frame(avctx, frame, &buffer);
662  if (ret < 0)
663  return ret;
664 
665  if (!s->pkt.size) {
666  /* fetch new packet or eof */
667  ret = ff_decode_get_packet(avctx, &s->pkt);
668  if (ret < 0 && ret != AVERROR_EOF)
669  return ret;
670  }
671 
672  // Wait input buffer
673  ff_mutex_lock(&s->input_mutex);
674  while (!s->decode_status) {
675  if (av_fifo_read(s->input_queue, &buffer, 1) >= 0)
676  break;
677  ff_cond_wait(&s->input_cond, &s->input_mutex);
678  }
679 
680  ret = s->decode_status;
681  ff_mutex_unlock(&s->input_mutex);
682 
683  if (ret < 0)
684  return ret;
685 
686  ret = oh_decode_send_pkt(avctx, &buffer);
687  if (ret < 0)
688  return ret;
689  }
690 
691  return AVERROR(EAGAIN);
692 }
693 
694 static void oh_decode_flush(AVCodecContext *avctx)
695 {
696  OHCodecDecContext *s = avctx->priv_data;
697 
698  OH_VideoDecoder_Flush(s->dec);
699 
700  ff_mutex_lock(&s->input_mutex);
701  ff_mutex_lock(&s->output_mutex);
702  av_fifo_reset2(s->input_queue);
703  av_fifo_reset2(s->output_queue);
704  s->decode_status = 0;
705  s->eof_sent = false;
706  ff_mutex_unlock(&s->output_mutex);
707  ff_mutex_unlock(&s->input_mutex);
708 
709  OH_VideoDecoder_Start(s->dec);
710 }
711 
712 static const AVCodecHWConfigInternal *const oh_hw_configs[] = {
713  &(const AVCodecHWConfigInternal) {
714  .public = {
718  .device_type = AV_HWDEVICE_TYPE_OHCODEC,
719  },
720  .hwaccel = NULL,
721  },
722  NULL
723 };
724 
725 #define VD (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM)
726 static const AVOption ohcodec_vdec_options[] = {
727  {"codec_name", "Select codec by name",
728  OFFSET(name), AV_OPT_TYPE_STRING, .flags = VD},
729  {"allow_sw", "Allow software decoding",
730  OFFSET(allow_sw), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, VD},
731  {NULL}
732 };
733 
734 #define DECLARE_OHCODEC_VCLASS(short_name) \
735  static const AVClass short_name##_oh_dec_class = { \
736  .class_name = #short_name "_ohcodec", \
737  .item_name = av_default_item_name, \
738  .option = ohcodec_vdec_options, \
739  .version = LIBAVUTIL_VERSION_INT, \
740  };
741 
742 #define DECLARE_OHCODEC_VDEC(short_name, full_name, codec_id, bsf) \
743  DECLARE_OHCODEC_VCLASS(short_name) \
744  const FFCodec ff_##short_name##_oh_decoder = { \
745  .p.name = #short_name "_ohcodec", \
746  CODEC_LONG_NAME(full_name " OpenHarmony Codec"), \
747  .p.type = AVMEDIA_TYPE_VIDEO, \
748  .p.id = codec_id, \
749  .p.priv_class = &short_name##_oh_dec_class, \
750  .priv_data_size = sizeof(OHCodecDecContext), \
751  .init = oh_decode_init, \
752  FF_CODEC_RECEIVE_FRAME_CB(oh_decode_receive_frame), \
753  .flush = oh_decode_flush, \
754  .close = oh_decode_close, \
755  .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING | \
756  AV_CODEC_CAP_HARDWARE, \
757  .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, \
758  .bsfs = bsf, \
759  .hw_configs = oh_hw_configs, \
760  .p.wrapper_name = "ohcodec", \
761  };
762 
763 #if CONFIG_H264_OH_DECODER
764 DECLARE_OHCODEC_VDEC(h264, "H.264", AV_CODEC_ID_H264, "h264_mp4toannexb")
765 #endif
766 
767 #if CONFIG_HEVC_OH_DECODER
768 DECLARE_OHCODEC_VDEC(hevc, "H.265", AV_CODEC_ID_HEVC, "hevc_mp4toannexb")
769 #endif
hwconfig.h
AVHWDeviceContext::hwctx
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
Definition: hwcontext.h:88
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: packet.c:433
ff_decode_get_packet
int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt)
Called by decoders to get the next packet for decoding.
Definition: decode.c:245
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
oh_decode_wrap_hw_buffer
static int oh_decode_wrap_hw_buffer(AVCodecContext *avctx, AVFrame *frame, OHBufferQueueItem *output, const OH_AVCodecBufferAttr *attr)
Definition: ohdec.c:453
name
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default minimum maximum flags name is the option name
Definition: writing_filters.txt:88
OHCodecDecContext::allow_sw
int allow_sw
Definition: ohdec.c:73
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
opt.h
AVCodecContext::colorspace
enum AVColorSpace colorspace
YUV colorspace type.
Definition: avcodec.h:659
OHCodecDecContext::input_cond
AVCond input_cond
Definition: ohdec.c:52
out
FILE * out
Definition: movenc.c:55
cb
static double cb(void *priv, double x, double y)
Definition: vf_geq.c:247
OHBufferQueueItem
Definition: ohcodec.h:33
thread.h
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
AVBufferRef::data
uint8_t * data
The data buffer.
Definition: buffer.h:90
AVRefStructOpaque
RefStruct is an API for creating reference-counted objects with minimal overhead.
Definition: refstruct.h:58
AV_TIME_BASE_Q
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:263
output
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce output
Definition: filter_design.txt:226
OHCodecDecContext::mutex_cond_cnt
unsigned mutex_cond_cnt
Definition: ohdec.c:74
oh_decode_on_output
static void oh_decode_on_output(OH_AVCodec *codec, uint32_t index, OH_AVBuffer *buffer, void *userdata)
Definition: ohdec.c:317
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:427
AVCodecContext::color_trc
enum AVColorTransferCharacteristic color_trc
Color Transfer Characteristic.
Definition: avcodec.h:652
AVCOL_RANGE_JPEG
@ AVCOL_RANGE_JPEG
Full range content.
Definition: pixfmt.h:767
AVOption
AVOption.
Definition: opt.h:429
data
const char data[16]
Definition: mxf.c:149
oh_decode_receive_frame
static int oh_decode_receive_frame(AVCodecContext *avctx, AVFrame *frame)
Definition: ohdec.c:636
OHCodecBuffer::buffer
OH_AVBuffer * buffer
Definition: ohdec.c:84
oh_decode_create
static int oh_decode_create(OHCodecDecContext *s, AVCodecContext *avctx)
Definition: ohdec.c:99
ff_set_dimensions
int ff_set_dimensions(AVCodecContext *s, int width, int height)
Check that the provided frame dimensions are valid and set them on the codec context.
Definition: utils.c:91
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:613
ff_pthread_free
av_cold void ff_pthread_free(void *obj, const unsigned offsets[])
Definition: pthread.c:92
ff_mutex_unlock
static int ff_mutex_unlock(AVMutex *mutex)
Definition: thread.h:189
window
static SDL_Window * window
Definition: ffplay.c:361
fifo.h
OHCodecDecContext::dec
OH_AVCodec * dec
Definition: ohdec.c:44
OHCodecDecContext::height
int height
Definition: ohdec.c:67
oh_decode_close
static av_cold int oh_decode_close(AVCodecContext *avctx)
Definition: ohdec.c:403
oh_decode_on_stream_changed
static void oh_decode_on_stream_changed(OH_AVCodec *codec, OH_AVFormat *format, void *userdata)
Definition: ohdec.c:219
av_fifo_write
int av_fifo_write(AVFifo *f, const void *buf, size_t nb_elems)
Write data into a FIFO.
Definition: fifo.c:188
AV_CODEC_HW_CONFIG_METHOD_AD_HOC
@ AV_CODEC_HW_CONFIG_METHOD_AD_HOC
The codec supports this format by some ad-hoc method.
Definition: codec.h:327
ohcodec.h
OHCodecDecContext::input_queue
AVFifo * input_queue
Definition: ohdec.c:53
OHCodecDecContext::avclass
AVClass * avclass
Definition: ohdec.c:43
av_image_fill_pointers
int av_image_fill_pointers(uint8_t *data[4], enum AVPixelFormat pix_fmt, int height, uint8_t *ptr, const int linesizes[4])
Fill plane data pointers for an image with pixel format pix_fmt and height height.
Definition: imgutils.c:145
refstruct.h
ff_oh_err_to_ff_err
int ff_oh_err_to_ff_err(OH_AVErrCode err)
Definition: ohcodec.c:25
AVHWDeviceContext
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition: hwcontext.h:63
AVCodecContext::color_primaries
enum AVColorPrimaries color_primaries
Chromaticity coordinates of the source primaries.
Definition: avcodec.h:645
pkt
AVPacket * pkt
Definition: movenc.c:60
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
av_cold
#define av_cold
Definition: attributes.h:106
av_fifo_read
int av_fifo_read(AVFifo *f, void *buf, size_t nb_elems)
Read data from a FIFO.
Definition: fifo.c:240
AVMutex
#define AVMutex
Definition: thread.h:184
OHCodecDecContext::pkt
AVPacket pkt
Definition: ohdec.c:59
av_image_fill_linesizes
int av_image_fill_linesizes(int linesizes[4], enum AVPixelFormat pix_fmt, int width)
Fill plane linesizes for an image with pixel format pix_fmt and width width.
Definition: imgutils.c:89
s
#define s(width, name)
Definition: cbs_vp9.c:198
OHCodecDecContext::output_mutex
AVMutex output_mutex
Definition: ohdec.c:55
OHCodecDecContext::decode_status
int decode_status
Definition: ohdec.c:61
OHCodecDecContext::eof_sent
bool eof_sent
Definition: ohdec.c:62
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
oh_buffer_release
static void oh_buffer_release(void *opaque, uint8_t *data)
Definition: ohdec.c:432
hwcontext_oh.h
OHCodecDecContext::input_mutex
AVMutex input_mutex
Definition: ohdec.c:51
ff_cond_wait
static int ff_cond_wait(AVCond *cond, AVMutex *mutex)
Definition: thread.h:198
av_refstruct_alloc_ext
static void * av_refstruct_alloc_ext(size_t size, unsigned flags, void *opaque, void(*free_cb)(AVRefStructOpaque opaque, void *obj))
A wrapper around av_refstruct_alloc_ext_c() for the common case of a non-const qualified opaque.
Definition: refstruct.h:94
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
oh_decode_on_need_input
static void oh_decode_on_need_input(OH_AVCodec *codec, uint32_t index, OH_AVBuffer *buffer, void *userdata)
Definition: ohdec.c:298
decode.h
AVCond
#define AVCond
Definition: thread.h:192
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
AVCodecHWConfig::pix_fmt
enum AVPixelFormat pix_fmt
For decoders, a hardware pixel format which that decoder may be able to decode to if suitable hardwar...
Definition: codec.h:339
av_hwdevice_get_type_name
const char * av_hwdevice_get_type_name(enum AVHWDeviceType type)
Get the string name of an AVHWDeviceType.
Definition: hwcontext.c:120
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:79
AVCodecContext::codec_id
enum AVCodecID codec_id
Definition: avcodec.h:441
OHCodecBuffer::dec_ref
OH_AVCodec ** dec_ref
RefStruct reference.
Definition: ohdec.c:85
oh_decode_send_pkt
static int oh_decode_send_pkt(AVCodecContext *avctx, OHBufferQueueItem *input)
Definition: ohdec.c:573
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:76
NULL
#define NULL
Definition: coverity.c:32
format
New swscale design to change SwsGraph is what coordinates multiple passes These can include cascaded scaling error diffusion and so on Or we could have separate passes for the vertical and horizontal scaling In between each SwsPass lies a fully allocated image buffer Graph passes may have different levels of e g we can have a single threaded error diffusion pass following a multi threaded scaling pass SwsGraph is internally recreated whenever the image format
Definition: swscale-v2.txt:14
AVCodecContext::color_range
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition: avcodec.h:669
oh_decode_release
static void oh_decode_release(AVRefStructOpaque unused, void *obj)
Definition: ohdec.c:88
OHCodecBuffer
Definition: ohdec.c:82
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
ff_set_sar
int ff_set_sar(AVCodecContext *avctx, AVRational sar)
Check that the provided sample aspect ratio is valid and set it on the codec context.
Definition: utils.c:106
oh_decode_set_format
static int oh_decode_set_format(OHCodecDecContext *s, AVCodecContext *avctx)
Definition: ohdec.c:144
pthread_internal.h
oh_decode_start
static int oh_decode_start(OHCodecDecContext *s, AVCodecContext *avctx)
Definition: ohdec.c:336
index
int index
Definition: gxfenc.c:90
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
AV_HWDEVICE_TYPE_OHCODEC
@ AV_HWDEVICE_TYPE_OHCODEC
Definition: hwcontext.h:43
OHCodecDecContext
Definition: ohdec.c:42
av_fifo_reset2
void av_fifo_reset2(AVFifo *f)
Definition: fifo.c:280
ff_oh_mime
static const char * ff_oh_mime(enum AVCodecID codec_id, void *log)
Definition: ohcodec.h:40
ff_get_buffer
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: decode.c:1720
AVPacket::size
int size
Definition: packet.h:559
AVFifo
Definition: fifo.c:35
codec_internal.h
OHCodecDecContext::stride
int stride
Definition: ohdec.c:68
OHCodecDecContext::pix_fmt
OH_AVPixelFormat pix_fmt
Definition: ohdec.c:70
av_err2str
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: error.h:122
AVCodecContext::pkt_timebase
AVRational pkt_timebase
Timebase in which pkt_dts/pts and AVPacket.dts/pts are expressed.
Definition: avcodec.h:542
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:247
VD
#define VD
Definition: ohdec.c:725
oh_decode_init
static av_cold int oh_decode_init(AVCodecContext *avctx)
Definition: ohdec.c:372
DEFINE_OFFSET_ARRAY
DEFINE_OFFSET_ARRAY(OHCodecDecContext, mutex_cond, mutex_cond_cnt,(OFFSET(input_mutex), OFFSET(output_mutex)),(OFFSET(input_cond), OFFSET(output_cond)))
AVCodecHWConfigInternal
Definition: hwconfig.h:25
oh_hw_configs
static const AVCodecHWConfigInternal *const oh_hw_configs[]
Definition: ohdec.c:712
oh_decode_wrap_sw_buffer
static int oh_decode_wrap_sw_buffer(AVCodecContext *avctx, AVFrame *frame, OHBufferQueueItem *output, const OH_AVCodecBufferAttr *attr)
Definition: ohdec.c:489
av_refstruct_ref
void * av_refstruct_ref(void *obj)
Create a new reference to an object managed via this API, i.e.
Definition: refstruct.c:140
OHCodecDecContext::width
int width
Definition: ohdec.c:66
AVERROR_EXTERNAL
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:59
ff_mutex_lock
static int ff_mutex_lock(AVMutex *mutex)
Definition: thread.h:188
input
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some input
Definition: filter_design.txt:172
OHCodecDecContext::name
char * name
Definition: ohdec.c:72
av_refstruct_unref
void av_refstruct_unref(void *objp)
Decrement the reference count of the underlying object and automatically free the object if there are...
Definition: refstruct.c:120
OHCodecBuffer::index
uint32_t index
Definition: ohdec.c:83
OHCodecDecContext::dec_ref
OH_AVCodec ** dec_ref
Definition: ohdec.c:49
AV_CODEC_ID_HEVC
@ AV_CODEC_ID_HEVC
Definition: codec_id.h:228
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
av_d2q
AVRational av_d2q(double d, int max)
Convert a double precision floating point number to a rational.
Definition: rational.c:106
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:256
AVCodecContext::hw_device_ctx
AVBufferRef * hw_device_ctx
A reference to the AVHWDeviceContext describing the device which will be used by a hardware encoder/d...
Definition: avcodec.h:1475
AVCodecContext::height
int height
Definition: avcodec.h:592
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:631
AVCOL_RANGE_MPEG
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition: pixfmt.h:750
avcodec.h
ret
ret
Definition: filter_design.txt:187
AVHWDeviceContext::type
enum AVHWDeviceType type
This field identifies the underlying API used for hardware access.
Definition: hwcontext.h:75
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
ohcodec_vdec_options
static const AVOption ohcodec_vdec_options[]
Definition: ohdec.c:726
av_fifo_alloc2
AVFifo * av_fifo_alloc2(size_t nb_elems, size_t elem_size, unsigned int flags)
Allocate and initialize an AVFifo with a given element size.
Definition: fifo.c:47
oh_decode_on_err
static void oh_decode_on_err(OH_AVCodec *codec, int32_t err, void *userdata)
Definition: ohdec.c:202
ff_decode_frame_props
int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame)
Set various frame properties from the codec context / packet data.
Definition: decode.c:1566
AVCodecContext
main external API structure.
Definition: avcodec.h:431
OHCodecDecContext::got_stream_info
bool got_stream_info
Definition: ohdec.c:65
buffer
the frame and frame reference mechanism is intended to as much as expensive copies of that data while still allowing the filters to produce correct results The data is stored in buffers represented by AVFrame structures Several references can point to the same frame buffer
Definition: filter_design.txt:49
av_image_copy2
static void av_image_copy2(uint8_t *const dst_data[4], const int dst_linesizes[4], uint8_t *const src_data[4], const int src_linesizes[4], enum AVPixelFormat pix_fmt, int width, int height)
Wrapper around av_image_copy() to workaround the limitation that the conversion from uint8_t * const ...
Definition: imgutils.h:184
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:72
OHCodecDecContext::output_to_window
bool output_to_window
Definition: ohdec.c:64
AVOHCodecDeviceContext
OpenHarmony codec device.
Definition: hwcontext_oh.h:27
ff_oh_pix_to_ff_pix
enum AVPixelFormat ff_oh_pix_to_ff_pix(OH_AVPixelFormat oh_pix)
Definition: ohcodec.c:63
ff_cond_signal
static int ff_cond_signal(AVCond *cond)
Definition: thread.h:196
Windows::Graphics::DirectX::Direct3D11::p
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
Definition: vsrc_gfxcapture_winrt.hpp:53
ff_pthread_init
av_cold int ff_pthread_init(void *obj, const unsigned offsets[])
Initialize/destroy a list of mutexes/conditions contained in a structure.
Definition: pthread.c:105
DECLARE_OHCODEC_VDEC
#define DECLARE_OHCODEC_VDEC(short_name, full_name, codec_id, bsf)
Definition: ohdec.c:742
mem.h
AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX
@ AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX
The codec supports this format via the hw_device_ctx interface.
Definition: codec.h:298
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
AV_PIX_FMT_OHCODEC
@ AV_PIX_FMT_OHCODEC
Definition: pixfmt.h:500
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:458
AVPacket
This structure stores compressed data.
Definition: packet.h:535
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition: opt.h:327
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:592
int32_t
int32_t
Definition: audioconvert.c:56
imgutils.h
oh_decode_flush
static void oh_decode_flush(AVCodecContext *avctx)
Definition: ohdec.c:694
AVERROR_BUG
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:52
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
av_fifo_freep2
void av_fifo_freep2(AVFifo **f)
Free an AVFifo and reset pointer to NULL.
Definition: fifo.c:286
oh_decode_output_frame
static int oh_decode_output_frame(AVCodecContext *avctx, AVFrame *frame, OHBufferQueueItem *output)
Definition: ohdec.c:535
OFFSET
#define OFFSET(x)
Definition: ohdec.c:77
AVOHCodecDeviceContext::native_window
void * native_window
Pointer to OHNativeWindow.
Definition: hwcontext_oh.h:31
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Underlying C type is a uint8_t* that is either NULL or points to a C string allocated with the av_mal...
Definition: opt.h:276
OHCodecDecContext::slice_height
int slice_height
Definition: ohdec.c:69
OHCodecDecContext::output_queue
AVFifo * output_queue
Definition: ohdec.c:57
AVCodecHWConfigInternal::public
AVCodecHWConfig public
This is the structure which will be returned to the user by avcodec_get_hw_config().
Definition: hwconfig.h:30
src
#define src
Definition: vp8dsp.c:248
fifo_size
size_t fifo_size
Definition: dts2pts.c:371
AV_FIFO_FLAG_AUTO_GROW
#define AV_FIFO_FLAG_AUTO_GROW
Automatically resize the FIFO on writes, so that the data fits.
Definition: fifo.h:63
OHCodecDecContext::output_cond
AVCond output_cond
Definition: ohdec.c:56