You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

252 lines
7.5KB

  1. /*
  2. * Copyright (c) 2018 Ronald S. Bultje <rsbultje gmail com>
  3. * Copyright (c) 2018 James Almer <jamrial gmail com>
  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. #include <dav1d/dav1d.h>
  22. #include "libavutil/avassert.h"
  23. #include "libavutil/opt.h"
  24. #include "avcodec.h"
  25. #include "decode.h"
  26. #include "internal.h"
  27. typedef struct Libdav1dContext {
  28. AVClass *class;
  29. Dav1dContext *c;
  30. Dav1dData data;
  31. int tile_threads;
  32. } Libdav1dContext;
  33. static av_cold int libdav1d_init(AVCodecContext *c)
  34. {
  35. Libdav1dContext *dav1d = c->priv_data;
  36. Dav1dSettings s;
  37. int res;
  38. av_log(c, AV_LOG_INFO, "libdav1d %s\n", dav1d_version());
  39. dav1d_default_settings(&s);
  40. s.n_tile_threads = dav1d->tile_threads;
  41. s.n_frame_threads = FFMIN(c->thread_count ? c->thread_count : av_cpu_count(), 256);
  42. res = dav1d_open(&dav1d->c, &s);
  43. if (res < 0)
  44. return AVERROR(ENOMEM);
  45. return 0;
  46. }
  47. static void libdav1d_flush(AVCodecContext *c)
  48. {
  49. Libdav1dContext *dav1d = c->priv_data;
  50. dav1d_data_unref(&dav1d->data);
  51. dav1d_flush(dav1d->c);
  52. }
  53. static void libdav1d_data_free(const uint8_t *data, void *opaque) {
  54. AVBufferRef *buf = opaque;
  55. av_buffer_unref(&buf);
  56. }
  57. static void libdav1d_frame_free(void *opaque, uint8_t *data) {
  58. Dav1dPicture p = { 0 };
  59. p.ref = opaque;
  60. p.data[0] = (void *) 0x1; // this has to be non-NULL
  61. dav1d_picture_unref(&p);
  62. }
  63. static const enum AVPixelFormat pix_fmt[][2] = {
  64. [DAV1D_PIXEL_LAYOUT_I400] = { AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY10 },
  65. [DAV1D_PIXEL_LAYOUT_I420] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV420P10 },
  66. [DAV1D_PIXEL_LAYOUT_I422] = { AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV422P10 },
  67. [DAV1D_PIXEL_LAYOUT_I444] = { AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV444P10 },
  68. };
  69. // TODO: Update once 12bit support is added.
  70. static const int profile[] = {
  71. [DAV1D_PIXEL_LAYOUT_I400] = FF_PROFILE_AV1_MAIN,
  72. [DAV1D_PIXEL_LAYOUT_I420] = FF_PROFILE_AV1_MAIN,
  73. [DAV1D_PIXEL_LAYOUT_I422] = FF_PROFILE_AV1_PROFESSIONAL,
  74. [DAV1D_PIXEL_LAYOUT_I444] = FF_PROFILE_AV1_HIGH,
  75. };
  76. static int libdav1d_receive_frame(AVCodecContext *c, AVFrame *frame)
  77. {
  78. Libdav1dContext *dav1d = c->priv_data;
  79. Dav1dData *data = &dav1d->data;
  80. Dav1dPicture p = { 0 };
  81. int res;
  82. if (!data->sz) {
  83. AVPacket pkt = { 0 };
  84. res = ff_decode_get_packet(c, &pkt);
  85. if (res < 0 && res != AVERROR_EOF)
  86. return res;
  87. if (pkt.size) {
  88. res = dav1d_data_wrap(data, pkt.data, pkt.size, libdav1d_data_free, pkt.buf);
  89. if (res < 0) {
  90. av_packet_unref(&pkt);
  91. return res;
  92. }
  93. data->m.timestamp = pkt.pts;
  94. data->m.offset = pkt.pos;
  95. data->m.duration = pkt.duration;
  96. pkt.buf = NULL;
  97. av_packet_unref(&pkt);
  98. }
  99. }
  100. res = dav1d_send_data(dav1d->c, data);
  101. if (res < 0) {
  102. if (res == -EINVAL)
  103. res = AVERROR_INVALIDDATA;
  104. if (res != -EAGAIN)
  105. return res;
  106. }
  107. res = dav1d_get_picture(dav1d->c, &p);
  108. if (res < 0) {
  109. if (res == -EINVAL)
  110. res = AVERROR_INVALIDDATA;
  111. else if (res == -EAGAIN && c->internal->draining)
  112. res = AVERROR_EOF;
  113. return res;
  114. }
  115. av_assert0(p.data[0] != NULL);
  116. frame->buf[0] = av_buffer_create(NULL, 0, libdav1d_frame_free,
  117. p.ref, AV_BUFFER_FLAG_READONLY);
  118. if (!frame->buf[0]) {
  119. dav1d_picture_unref(&p);
  120. return AVERROR(ENOMEM);
  121. }
  122. frame->data[0] = p.data[0];
  123. frame->data[1] = p.data[1];
  124. frame->data[2] = p.data[2];
  125. frame->linesize[0] = p.stride[0];
  126. frame->linesize[1] = p.stride[1];
  127. frame->linesize[2] = p.stride[1];
  128. c->profile = profile[p.p.layout];
  129. frame->format = c->pix_fmt = pix_fmt[p.p.layout][p.p.bpc == 10];
  130. frame->width = p.p.w;
  131. frame->height = p.p.h;
  132. if (c->width != p.p.w || c->height != p.p.h) {
  133. res = ff_set_dimensions(c, p.p.w, p.p.h);
  134. if (res < 0)
  135. return res;
  136. }
  137. switch (p.seq_hdr->chr) {
  138. case DAV1D_CHR_VERTICAL:
  139. frame->chroma_location = c->chroma_sample_location = AVCHROMA_LOC_LEFT;
  140. break;
  141. case DAV1D_CHR_COLOCATED:
  142. frame->chroma_location = c->chroma_sample_location = AVCHROMA_LOC_TOPLEFT;
  143. break;
  144. }
  145. frame->colorspace = c->colorspace = (enum AVColorSpace) p.seq_hdr->mtrx;
  146. frame->color_primaries = c->color_primaries = (enum AVColorPrimaries) p.seq_hdr->pri;
  147. frame->color_trc = c->color_trc = (enum AVColorTransferCharacteristic) p.seq_hdr->trc;
  148. frame->color_range = c->color_range = p.seq_hdr->color_range ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
  149. // match timestamps and packet size
  150. frame->pts = frame->best_effort_timestamp = p.m.timestamp;
  151. #if FF_API_PKT_PTS
  152. FF_DISABLE_DEPRECATION_WARNINGS
  153. frame->pkt_pts = p.m.timestamp;
  154. FF_ENABLE_DEPRECATION_WARNINGS
  155. #endif
  156. frame->pkt_dts = p.m.timestamp;
  157. frame->pkt_pos = p.m.offset;
  158. frame->pkt_size = p.m.size;
  159. frame->pkt_duration = p.m.duration;
  160. frame->key_frame = p.frame_hdr->frame_type == DAV1D_FRAME_TYPE_KEY;
  161. switch (p.frame_hdr->frame_type) {
  162. case DAV1D_FRAME_TYPE_KEY:
  163. case DAV1D_FRAME_TYPE_INTRA:
  164. frame->pict_type = AV_PICTURE_TYPE_I;
  165. break;
  166. case DAV1D_FRAME_TYPE_INTER:
  167. frame->pict_type = AV_PICTURE_TYPE_P;
  168. break;
  169. case DAV1D_FRAME_TYPE_SWITCH:
  170. frame->pict_type = AV_PICTURE_TYPE_SP;
  171. break;
  172. default:
  173. return AVERROR_INVALIDDATA;
  174. }
  175. return 0;
  176. }
  177. static av_cold int libdav1d_close(AVCodecContext *c)
  178. {
  179. Libdav1dContext *dav1d = c->priv_data;
  180. dav1d_data_unref(&dav1d->data);
  181. dav1d_close(&dav1d->c);
  182. return 0;
  183. }
  184. #define OFFSET(x) offsetof(Libdav1dContext, x)
  185. #define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
  186. static const AVOption libdav1d_options[] = {
  187. { "tilethreads", "Tile threads", OFFSET(tile_threads), AV_OPT_TYPE_INT, { .i64 = 1 }, 1, 64, VD, NULL },
  188. { NULL }
  189. };
  190. static const AVClass libdav1d_class = {
  191. .class_name = "libdav1d decoder",
  192. .item_name = av_default_item_name,
  193. .option = libdav1d_options,
  194. .version = LIBAVUTIL_VERSION_INT,
  195. };
  196. AVCodec ff_libdav1d_decoder = {
  197. .name = "libdav1d",
  198. .long_name = NULL_IF_CONFIG_SMALL("dav1d AV1 decoder by VideoLAN"),
  199. .type = AVMEDIA_TYPE_VIDEO,
  200. .id = AV_CODEC_ID_AV1,
  201. .priv_data_size = sizeof(Libdav1dContext),
  202. .init = libdav1d_init,
  203. .close = libdav1d_close,
  204. .flush = libdav1d_flush,
  205. .receive_frame = libdav1d_receive_frame,
  206. .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS,
  207. .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_SETS_PKT_DTS,
  208. .priv_class = &libdav1d_class,
  209. .wrapper_name = "libdav1d",
  210. };