libdiracenc.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422
  1. /*
  2. * Dirac encoding support via libdirac library
  3. * Copyright (c) 2005 BBC, Andrew Kennedy <dirac at rd dot bbc dot co dot uk>
  4. * Copyright (c) 2006-2008 BBC, Anuradha Suraparaju <asuraparaju at gmail dot com >
  5. *
  6. * This file is part of FFmpeg.
  7. *
  8. * FFmpeg is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Lesser General Public
  10. * License as published by the Free Software Foundation; either
  11. * version 2.1 of the License, or (at your option) any later version.
  12. *
  13. * FFmpeg is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * Lesser General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with FFmpeg; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21. */
  22. /**
  23. * @file libavcodec/libdiracenc.c
  24. * Dirac encoding support via libdirac library; more details about the
  25. * Dirac project can be found at http://dirac.sourceforge.net/.
  26. * The libdirac_encoder library implements Dirac specification version 2.2
  27. * (http://dirac.sourceforge.net/specification.html).
  28. */
  29. #include "libdirac_libschro.h"
  30. #include "libdirac.h"
  31. #undef NDEBUG
  32. #include <assert.h>
  33. #include <libdirac_encoder/dirac_encoder.h>
  34. /** Dirac encoder private data */
  35. typedef struct FfmpegDiracEncoderParams
  36. {
  37. /** Dirac encoder context */
  38. dirac_encoder_context_t enc_ctx;
  39. /** frame being encoded */
  40. AVFrame picture;
  41. /** frame size */
  42. int frame_size;
  43. /** Dirac encoder handle */
  44. dirac_encoder_t* p_encoder;
  45. /** input frame buffer */
  46. unsigned char *p_in_frame_buf;
  47. /** buffer to store encoder output before writing it to the frame queue */
  48. unsigned char *enc_buf;
  49. /** size of encoder buffer */
  50. int enc_buf_size;
  51. /** queue storing encoded frames */
  52. FfmpegDiracSchroQueue enc_frame_queue;
  53. /** end of sequence signalled by user, 0 - false, 1 - true */
  54. int eos_signalled;
  55. /** end of sequence returned by encoder, 0 - false, 1 - true */
  56. int eos_pulled;
  57. } FfmpegDiracEncoderParams;
  58. /**
  59. * Works out Dirac-compatible chroma format.
  60. */
  61. static dirac_chroma_t GetDiracChromaFormat(enum PixelFormat ff_pix_fmt)
  62. {
  63. int num_formats = sizeof(ffmpeg_dirac_pixel_format_map) /
  64. sizeof(ffmpeg_dirac_pixel_format_map[0]);
  65. int idx;
  66. for (idx = 0; idx < num_formats; ++idx) {
  67. if (ffmpeg_dirac_pixel_format_map[idx].ff_pix_fmt == ff_pix_fmt) {
  68. return ffmpeg_dirac_pixel_format_map[idx].dirac_pix_fmt;
  69. }
  70. }
  71. return formatNK;
  72. }
  73. /**
  74. * Dirac video preset table. Ensure that this tables matches up correctly
  75. * with the ff_dirac_schro_video_format_info table in libdirac_libschro.c.
  76. */
  77. static const VideoFormat ff_dirac_video_formats[]={
  78. VIDEO_FORMAT_CUSTOM ,
  79. VIDEO_FORMAT_QSIF525 ,
  80. VIDEO_FORMAT_QCIF ,
  81. VIDEO_FORMAT_SIF525 ,
  82. VIDEO_FORMAT_CIF ,
  83. VIDEO_FORMAT_4SIF525 ,
  84. VIDEO_FORMAT_4CIF ,
  85. VIDEO_FORMAT_SD_480I60 ,
  86. VIDEO_FORMAT_SD_576I50 ,
  87. VIDEO_FORMAT_HD_720P60 ,
  88. VIDEO_FORMAT_HD_720P50 ,
  89. VIDEO_FORMAT_HD_1080I60 ,
  90. VIDEO_FORMAT_HD_1080I50 ,
  91. VIDEO_FORMAT_HD_1080P60 ,
  92. VIDEO_FORMAT_HD_1080P50 ,
  93. VIDEO_FORMAT_DIGI_CINEMA_2K24 ,
  94. VIDEO_FORMAT_DIGI_CINEMA_4K24 ,
  95. };
  96. /**
  97. * Returns the video format preset matching the input video dimensions and
  98. * time base.
  99. */
  100. static VideoFormat GetDiracVideoFormatPreset (AVCodecContext *avccontext)
  101. {
  102. unsigned int num_formats = sizeof(ff_dirac_video_formats) /
  103. sizeof(ff_dirac_video_formats[0]);
  104. unsigned int idx = ff_dirac_schro_get_video_format_idx (avccontext);
  105. return (idx < num_formats) ?
  106. ff_dirac_video_formats[idx] : VIDEO_FORMAT_CUSTOM;
  107. }
  108. static av_cold int libdirac_encode_init(AVCodecContext *avccontext)
  109. {
  110. FfmpegDiracEncoderParams* p_dirac_params = avccontext->priv_data;
  111. int no_local = 1;
  112. int verbose = avccontext->debug;
  113. VideoFormat preset;
  114. /* get Dirac preset */
  115. preset = GetDiracVideoFormatPreset(avccontext);
  116. /* initialize the encoder context */
  117. dirac_encoder_context_init (&(p_dirac_params->enc_ctx), preset);
  118. p_dirac_params->enc_ctx.src_params.chroma =
  119. GetDiracChromaFormat(avccontext->pix_fmt);
  120. if (p_dirac_params->enc_ctx.src_params.chroma == formatNK) {
  121. av_log (avccontext, AV_LOG_ERROR,
  122. "Unsupported pixel format %d. This codec supports only "
  123. "Planar YUV formats (yuv420p, yuv422p, yuv444p\n",
  124. avccontext->pix_fmt);
  125. return -1;
  126. }
  127. p_dirac_params->enc_ctx.src_params.frame_rate.numerator =
  128. avccontext->time_base.den;
  129. p_dirac_params->enc_ctx.src_params.frame_rate.denominator =
  130. avccontext->time_base.num;
  131. p_dirac_params->enc_ctx.src_params.width = avccontext->width;
  132. p_dirac_params->enc_ctx.src_params.height = avccontext->height;
  133. p_dirac_params->frame_size = avpicture_get_size(avccontext->pix_fmt,
  134. avccontext->width,
  135. avccontext->height);
  136. avccontext->coded_frame = &p_dirac_params->picture;
  137. if (no_local) {
  138. p_dirac_params->enc_ctx.decode_flag = 0;
  139. p_dirac_params->enc_ctx.instr_flag = 0;
  140. } else {
  141. p_dirac_params->enc_ctx.decode_flag = 1;
  142. p_dirac_params->enc_ctx.instr_flag = 1;
  143. }
  144. /* Intra-only sequence */
  145. if (avccontext->gop_size == 0 ) {
  146. p_dirac_params->enc_ctx.enc_params.num_L1 = 0;
  147. if (avccontext->coder_type == FF_CODER_TYPE_VLC)
  148. p_dirac_params->enc_ctx.enc_params.using_ac = 0;
  149. } else
  150. avccontext->has_b_frames = 1;
  151. if (avccontext->flags & CODEC_FLAG_QSCALE) {
  152. if (avccontext->global_quality != 0) {
  153. p_dirac_params->enc_ctx.enc_params.qf =
  154. avccontext->global_quality / (FF_QP2LAMBDA*10.0);
  155. /* if it is not default bitrate then send target rate. */
  156. if (avccontext->bit_rate >= 1000 &&
  157. avccontext->bit_rate != 200000) {
  158. p_dirac_params->enc_ctx.enc_params.trate =
  159. avccontext->bit_rate / 1000;
  160. }
  161. } else
  162. p_dirac_params->enc_ctx.enc_params.lossless = 1;
  163. } else if (avccontext->bit_rate >= 1000)
  164. p_dirac_params->enc_ctx.enc_params.trate = avccontext->bit_rate / 1000;
  165. if ((preset > VIDEO_FORMAT_QCIF || preset < VIDEO_FORMAT_QSIF525) &&
  166. avccontext->bit_rate == 200000) {
  167. p_dirac_params->enc_ctx.enc_params.trate = 0;
  168. }
  169. if (avccontext->flags & CODEC_FLAG_INTERLACED_ME) {
  170. /* all material can be coded as interlaced or progressive
  171. * irrespective of the type of source material */
  172. p_dirac_params->enc_ctx.enc_params.picture_coding_mode = 1;
  173. }
  174. p_dirac_params->p_encoder = dirac_encoder_init (&(p_dirac_params->enc_ctx),
  175. verbose );
  176. if (!p_dirac_params->p_encoder) {
  177. av_log(avccontext, AV_LOG_ERROR,
  178. "Unrecoverable Error: dirac_encoder_init failed. ");
  179. return EXIT_FAILURE;
  180. }
  181. /* allocate enough memory for the incoming data */
  182. p_dirac_params->p_in_frame_buf = av_malloc(p_dirac_params->frame_size);
  183. /* initialize the encoded frame queue */
  184. ff_dirac_schro_queue_init(&p_dirac_params->enc_frame_queue);
  185. return 0 ;
  186. }
  187. static void DiracFreeFrame (void *data)
  188. {
  189. FfmpegDiracSchroEncodedFrame *enc_frame = data;
  190. av_freep (&(enc_frame->p_encbuf));
  191. av_free(enc_frame);
  192. }
  193. static int libdirac_encode_frame(AVCodecContext *avccontext,
  194. unsigned char *frame,
  195. int buf_size, void *data)
  196. {
  197. int enc_size = 0;
  198. dirac_encoder_state_t state;
  199. FfmpegDiracEncoderParams* p_dirac_params = avccontext->priv_data;
  200. FfmpegDiracSchroEncodedFrame* p_frame_output = NULL;
  201. FfmpegDiracSchroEncodedFrame* p_next_output_frame = NULL;
  202. int go = 1;
  203. int last_frame_in_sequence = 0;
  204. if (data == NULL) {
  205. /* push end of sequence if not already signalled */
  206. if (!p_dirac_params->eos_signalled) {
  207. dirac_encoder_end_sequence( p_dirac_params->p_encoder );
  208. p_dirac_params->eos_signalled = 1;
  209. }
  210. } else {
  211. /* Allocate frame data to Dirac input buffer.
  212. * Input line size may differ from what the codec supports,
  213. * especially when transcoding from one format to another.
  214. * So use avpicture_layout to copy the frame. */
  215. avpicture_layout ((AVPicture *)data, avccontext->pix_fmt,
  216. avccontext->width, avccontext->height,
  217. p_dirac_params->p_in_frame_buf,
  218. p_dirac_params->frame_size);
  219. /* load next frame */
  220. if (dirac_encoder_load (p_dirac_params->p_encoder,
  221. p_dirac_params->p_in_frame_buf,
  222. p_dirac_params->frame_size ) < 0) {
  223. av_log(avccontext, AV_LOG_ERROR, "Unrecoverable Encoder Error."
  224. " dirac_encoder_load failed...\n");
  225. return -1;
  226. }
  227. }
  228. if (p_dirac_params->eos_pulled)
  229. go = 0;
  230. while(go) {
  231. p_dirac_params->p_encoder->enc_buf.buffer = frame;
  232. p_dirac_params->p_encoder->enc_buf.size = buf_size;
  233. /* process frame */
  234. state = dirac_encoder_output ( p_dirac_params->p_encoder );
  235. switch (state)
  236. {
  237. case ENC_STATE_AVAIL:
  238. case ENC_STATE_EOS:
  239. assert (p_dirac_params->p_encoder->enc_buf.size > 0);
  240. /* All non-frame data is prepended to actual frame data to
  241. * be able to set the pts correctly. So we don't write data
  242. * to the frame output queue until we actually have a frame
  243. */
  244. p_dirac_params->enc_buf = av_realloc (
  245. p_dirac_params->enc_buf,
  246. p_dirac_params->enc_buf_size +
  247. p_dirac_params->p_encoder->enc_buf.size
  248. );
  249. memcpy(p_dirac_params->enc_buf + p_dirac_params->enc_buf_size,
  250. p_dirac_params->p_encoder->enc_buf.buffer,
  251. p_dirac_params->p_encoder->enc_buf.size);
  252. p_dirac_params->enc_buf_size +=
  253. p_dirac_params->p_encoder->enc_buf.size;
  254. if (state == ENC_STATE_EOS) {
  255. p_dirac_params->eos_pulled = 1;
  256. go = 0;
  257. }
  258. /* If non-frame data, don't output it until it we get an
  259. * encoded frame back from the encoder. */
  260. if (p_dirac_params->p_encoder->enc_pparams.pnum == -1)
  261. break;
  262. /* create output frame */
  263. p_frame_output = av_mallocz(sizeof(FfmpegDiracSchroEncodedFrame));
  264. /* set output data */
  265. p_frame_output->size = p_dirac_params->enc_buf_size;
  266. p_frame_output->p_encbuf = p_dirac_params->enc_buf;
  267. p_frame_output->frame_num =
  268. p_dirac_params->p_encoder->enc_pparams.pnum;
  269. if (p_dirac_params->p_encoder->enc_pparams.ptype == INTRA_PICTURE &&
  270. p_dirac_params->p_encoder->enc_pparams.rtype == REFERENCE_PICTURE)
  271. p_frame_output->key_frame = 1;
  272. ff_dirac_schro_queue_push_back (&p_dirac_params->enc_frame_queue,
  273. p_frame_output);
  274. p_dirac_params->enc_buf_size = 0;
  275. p_dirac_params->enc_buf = NULL;
  276. break;
  277. case ENC_STATE_BUFFER:
  278. go = 0;
  279. break;
  280. case ENC_STATE_INVALID:
  281. av_log(avccontext, AV_LOG_ERROR,
  282. "Unrecoverable Dirac Encoder Error. Quitting...\n");
  283. return -1;
  284. default:
  285. av_log(avccontext, AV_LOG_ERROR, "Unknown Dirac Encoder state\n");
  286. return -1;
  287. }
  288. }
  289. /* copy 'next' frame in queue */
  290. if (p_dirac_params->enc_frame_queue.size == 1 &&
  291. p_dirac_params->eos_pulled)
  292. last_frame_in_sequence = 1;
  293. p_next_output_frame =
  294. ff_dirac_schro_queue_pop(&p_dirac_params->enc_frame_queue);
  295. if (p_next_output_frame == NULL)
  296. return 0;
  297. memcpy(frame, p_next_output_frame->p_encbuf, p_next_output_frame->size);
  298. avccontext->coded_frame->key_frame = p_next_output_frame->key_frame;
  299. /* Use the frame number of the encoded frame as the pts. It is OK to do
  300. * so since Dirac is a constant framerate codec. It expects input to be
  301. * of constant framerate. */
  302. avccontext->coded_frame->pts = p_next_output_frame->frame_num;
  303. enc_size = p_next_output_frame->size;
  304. /* Append the end of sequence information to the last frame in the
  305. * sequence. */
  306. if (last_frame_in_sequence && p_dirac_params->enc_buf_size > 0)
  307. {
  308. memcpy (frame + enc_size, p_dirac_params->enc_buf,
  309. p_dirac_params->enc_buf_size);
  310. enc_size += p_dirac_params->enc_buf_size;
  311. av_freep (&p_dirac_params->enc_buf);
  312. p_dirac_params->enc_buf_size = 0;
  313. }
  314. /* free frame */
  315. DiracFreeFrame(p_next_output_frame);
  316. return enc_size;
  317. }
  318. static av_cold int libdirac_encode_close(AVCodecContext *avccontext)
  319. {
  320. FfmpegDiracEncoderParams* p_dirac_params = avccontext->priv_data;
  321. /* close the encoder */
  322. dirac_encoder_close(p_dirac_params->p_encoder );
  323. /* free data in the output frame queue */
  324. ff_dirac_schro_queue_free(&p_dirac_params->enc_frame_queue,
  325. DiracFreeFrame);
  326. /* free the encoder buffer */
  327. if (p_dirac_params->enc_buf_size)
  328. av_freep(&p_dirac_params->enc_buf);
  329. /* free the input frame buffer */
  330. av_freep(&p_dirac_params->p_in_frame_buf);
  331. return 0 ;
  332. }
  333. AVCodec libdirac_encoder = {
  334. "libdirac",
  335. CODEC_TYPE_VIDEO,
  336. CODEC_ID_DIRAC,
  337. sizeof(FfmpegDiracEncoderParams),
  338. libdirac_encode_init,
  339. libdirac_encode_frame,
  340. libdirac_encode_close,
  341. .capabilities= CODEC_CAP_DELAY,
  342. .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_YUV444P, PIX_FMT_NONE},
  343. .long_name= NULL_IF_CONFIG_SMALL("libdirac Dirac 2.2"),
  344. } ;