Commit | Line | Data |
---|---|---|
2ba45a60 DM |
1 | /* |
2 | * Dirac encoder support via Schroedinger libraries | |
3 | * Copyright (c) 2008 BBC, Anuradha Suraparaju <asuraparaju at gmail dot 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 | ||
22 | /** | |
23 | * @file | |
24 | * Dirac encoder support via libschroedinger-1.0 libraries. More details about | |
25 | * the Schroedinger project can be found at http://www.diracvideo.org/. | |
26 | * The library implements Dirac Specification Version 2.2 | |
27 | * (http://dirac.sourceforge.net/specification.html). | |
28 | */ | |
29 | ||
30 | #include <schroedinger/schro.h> | |
31 | #include <schroedinger/schrodebug.h> | |
32 | #include <schroedinger/schrovideoformat.h> | |
33 | ||
34 | #include "libavutil/attributes.h" | |
35 | #include "libavutil/avassert.h" | |
36 | #include "avcodec.h" | |
37 | #include "internal.h" | |
38 | #include "libschroedinger.h" | |
39 | #include "bytestream.h" | |
40 | ||
41 | ||
42 | /** libschroedinger encoder private data */ | |
43 | typedef struct SchroEncoderParams { | |
44 | /** Schroedinger video format */ | |
45 | SchroVideoFormat *format; | |
46 | ||
47 | /** Schroedinger frame format */ | |
48 | SchroFrameFormat frame_format; | |
49 | ||
50 | /** frame size */ | |
51 | int frame_size; | |
52 | ||
53 | /** Schroedinger encoder handle*/ | |
54 | SchroEncoder* encoder; | |
55 | ||
56 | /** buffer to store encoder output before writing it to the frame queue*/ | |
57 | unsigned char *enc_buf; | |
58 | ||
59 | /** Size of encoder buffer*/ | |
60 | int enc_buf_size; | |
61 | ||
62 | /** queue storing encoded frames */ | |
63 | FFSchroQueue enc_frame_queue; | |
64 | ||
65 | /** end of sequence signalled */ | |
66 | int eos_signalled; | |
67 | ||
68 | /** end of sequence pulled */ | |
69 | int eos_pulled; | |
70 | ||
71 | /* counter for frames submitted to encoder, used as dts */ | |
72 | int64_t dts; | |
73 | } SchroEncoderParams; | |
74 | ||
75 | /** | |
76 | * Works out Schro-compatible chroma format. | |
77 | */ | |
78 | static int set_chroma_format(AVCodecContext *avctx) | |
79 | { | |
80 | int num_formats = sizeof(schro_pixel_format_map) / | |
81 | sizeof(schro_pixel_format_map[0]); | |
82 | int idx; | |
83 | ||
84 | SchroEncoderParams *p_schro_params = avctx->priv_data; | |
85 | ||
86 | for (idx = 0; idx < num_formats; ++idx) { | |
87 | if (schro_pixel_format_map[idx].ff_pix_fmt == avctx->pix_fmt) { | |
88 | p_schro_params->format->chroma_format = | |
89 | schro_pixel_format_map[idx].schro_pix_fmt; | |
90 | return 0; | |
91 | } | |
92 | } | |
93 | ||
94 | av_log(avctx, AV_LOG_ERROR, | |
95 | "This codec currently only supports planar YUV 4:2:0, 4:2:2" | |
96 | " and 4:4:4 formats.\n"); | |
97 | ||
98 | return -1; | |
99 | } | |
100 | ||
101 | static av_cold int libschroedinger_encode_init(AVCodecContext *avctx) | |
102 | { | |
103 | SchroEncoderParams *p_schro_params = avctx->priv_data; | |
104 | SchroVideoFormatEnum preset; | |
105 | ||
106 | /* Initialize the libraries that libschroedinger depends on. */ | |
107 | schro_init(); | |
108 | ||
109 | /* Create an encoder object. */ | |
110 | p_schro_params->encoder = schro_encoder_new(); | |
111 | ||
112 | if (!p_schro_params->encoder) { | |
113 | av_log(avctx, AV_LOG_ERROR, | |
114 | "Unrecoverable Error: schro_encoder_new failed. "); | |
115 | return -1; | |
116 | } | |
117 | ||
118 | /* Initialize the format. */ | |
119 | preset = ff_get_schro_video_format_preset(avctx); | |
120 | p_schro_params->format = | |
121 | schro_encoder_get_video_format(p_schro_params->encoder); | |
122 | schro_video_format_set_std_video_format(p_schro_params->format, preset); | |
123 | p_schro_params->format->width = avctx->width; | |
124 | p_schro_params->format->height = avctx->height; | |
125 | ||
126 | if (set_chroma_format(avctx) == -1) | |
127 | return -1; | |
128 | ||
129 | if (avctx->color_primaries == AVCOL_PRI_BT709) { | |
130 | p_schro_params->format->colour_primaries = SCHRO_COLOUR_PRIMARY_HDTV; | |
131 | } else if (avctx->color_primaries == AVCOL_PRI_BT470BG) { | |
132 | p_schro_params->format->colour_primaries = SCHRO_COLOUR_PRIMARY_SDTV_625; | |
133 | } else if (avctx->color_primaries == AVCOL_PRI_SMPTE170M) { | |
134 | p_schro_params->format->colour_primaries = SCHRO_COLOUR_PRIMARY_SDTV_525; | |
135 | } | |
136 | ||
137 | if (avctx->colorspace == AVCOL_SPC_BT709) { | |
138 | p_schro_params->format->colour_matrix = SCHRO_COLOUR_MATRIX_HDTV; | |
139 | } else if (avctx->colorspace == AVCOL_SPC_BT470BG) { | |
140 | p_schro_params->format->colour_matrix = SCHRO_COLOUR_MATRIX_SDTV; | |
141 | } | |
142 | ||
143 | if (avctx->color_trc == AVCOL_TRC_BT709) { | |
144 | p_schro_params->format->transfer_function = SCHRO_TRANSFER_CHAR_TV_GAMMA; | |
145 | } | |
146 | ||
147 | if (ff_get_schro_frame_format(p_schro_params->format->chroma_format, | |
148 | &p_schro_params->frame_format) == -1) { | |
149 | av_log(avctx, AV_LOG_ERROR, | |
150 | "This codec currently supports only planar YUV 4:2:0, 4:2:2" | |
151 | " and 4:4:4 formats.\n"); | |
152 | return -1; | |
153 | } | |
154 | ||
155 | p_schro_params->format->frame_rate_numerator = avctx->time_base.den; | |
156 | p_schro_params->format->frame_rate_denominator = avctx->time_base.num; | |
157 | ||
158 | p_schro_params->frame_size = avpicture_get_size(avctx->pix_fmt, | |
159 | avctx->width, | |
160 | avctx->height); | |
161 | ||
162 | avctx->coded_frame = av_frame_alloc(); | |
163 | if (!avctx->coded_frame) | |
164 | return AVERROR(ENOMEM); | |
165 | ||
166 | if (!avctx->gop_size) { | |
167 | schro_encoder_setting_set_double(p_schro_params->encoder, | |
168 | "gop_structure", | |
169 | SCHRO_ENCODER_GOP_INTRA_ONLY); | |
170 | ||
171 | if (avctx->coder_type == FF_CODER_TYPE_VLC) | |
172 | schro_encoder_setting_set_double(p_schro_params->encoder, | |
173 | "enable_noarith", 1); | |
174 | } else { | |
175 | schro_encoder_setting_set_double(p_schro_params->encoder, | |
176 | "au_distance", avctx->gop_size); | |
177 | avctx->has_b_frames = 1; | |
178 | p_schro_params->dts = -1; | |
179 | } | |
180 | ||
181 | /* FIXME - Need to handle SCHRO_ENCODER_RATE_CONTROL_LOW_DELAY. */ | |
182 | if (avctx->flags & CODEC_FLAG_QSCALE) { | |
183 | if (!avctx->global_quality) { | |
184 | /* lossless coding */ | |
185 | schro_encoder_setting_set_double(p_schro_params->encoder, | |
186 | "rate_control", | |
187 | SCHRO_ENCODER_RATE_CONTROL_LOSSLESS); | |
188 | } else { | |
189 | int quality; | |
190 | schro_encoder_setting_set_double(p_schro_params->encoder, | |
191 | "rate_control", | |
192 | SCHRO_ENCODER_RATE_CONTROL_CONSTANT_QUALITY); | |
193 | ||
194 | quality = avctx->global_quality / FF_QP2LAMBDA; | |
195 | if (quality > 10) | |
196 | quality = 10; | |
197 | schro_encoder_setting_set_double(p_schro_params->encoder, | |
198 | "quality", quality); | |
199 | } | |
200 | } else { | |
201 | schro_encoder_setting_set_double(p_schro_params->encoder, | |
202 | "rate_control", | |
203 | SCHRO_ENCODER_RATE_CONTROL_CONSTANT_BITRATE); | |
204 | ||
205 | schro_encoder_setting_set_double(p_schro_params->encoder, | |
206 | "bitrate", avctx->bit_rate); | |
207 | } | |
208 | ||
209 | if (avctx->flags & CODEC_FLAG_INTERLACED_ME) | |
210 | /* All material can be coded as interlaced or progressive | |
211 | irrespective of the type of source material. */ | |
212 | schro_encoder_setting_set_double(p_schro_params->encoder, | |
213 | "interlaced_coding", 1); | |
214 | ||
215 | schro_encoder_setting_set_double(p_schro_params->encoder, "open_gop", | |
216 | !(avctx->flags & CODEC_FLAG_CLOSED_GOP)); | |
217 | ||
218 | /* FIXME: Signal range hardcoded to 8-bit data until both libschroedinger | |
219 | * and libdirac support other bit-depth data. */ | |
220 | schro_video_format_set_std_signal_range(p_schro_params->format, | |
221 | SCHRO_SIGNAL_RANGE_8BIT_VIDEO); | |
222 | ||
223 | /* Set the encoder format. */ | |
224 | schro_encoder_set_video_format(p_schro_params->encoder, | |
225 | p_schro_params->format); | |
226 | ||
227 | /* Set the debug level. */ | |
228 | schro_debug_set_level(avctx->debug); | |
229 | ||
230 | schro_encoder_start(p_schro_params->encoder); | |
231 | ||
232 | /* Initialize the encoded frame queue. */ | |
233 | ff_schro_queue_init(&p_schro_params->enc_frame_queue); | |
234 | return 0; | |
235 | } | |
236 | ||
237 | static SchroFrame *libschroedinger_frame_from_data(AVCodecContext *avctx, | |
238 | const AVFrame *frame) | |
239 | { | |
240 | SchroEncoderParams *p_schro_params = avctx->priv_data; | |
241 | SchroFrame *in_frame; | |
242 | /* Input line size may differ from what the codec supports. Especially | |
243 | * when transcoding from one format to another. So use avpicture_layout | |
244 | * to copy the frame. */ | |
245 | in_frame = ff_create_schro_frame(avctx, p_schro_params->frame_format); | |
246 | ||
247 | if (in_frame) | |
248 | avpicture_layout((const AVPicture *)frame, avctx->pix_fmt, | |
249 | avctx->width, avctx->height, | |
250 | in_frame->components[0].data, | |
251 | p_schro_params->frame_size); | |
252 | ||
253 | return in_frame; | |
254 | } | |
255 | ||
256 | static void libschroedinger_free_frame(void *data) | |
257 | { | |
258 | FFSchroEncodedFrame *enc_frame = data; | |
259 | ||
260 | av_freep(&enc_frame->p_encbuf); | |
261 | av_free(enc_frame); | |
262 | } | |
263 | ||
264 | static int libschroedinger_encode_frame(AVCodecContext *avctx, AVPacket *pkt, | |
265 | const AVFrame *frame, int *got_packet) | |
266 | { | |
267 | int enc_size = 0; | |
268 | SchroEncoderParams *p_schro_params = avctx->priv_data; | |
269 | SchroEncoder *encoder = p_schro_params->encoder; | |
270 | struct FFSchroEncodedFrame *p_frame_output = NULL; | |
271 | int go = 1; | |
272 | SchroBuffer *enc_buf; | |
273 | int presentation_frame; | |
274 | int parse_code; | |
275 | int last_frame_in_sequence = 0; | |
276 | int pkt_size, ret; | |
277 | ||
278 | if (!frame) { | |
279 | /* Push end of sequence if not already signalled. */ | |
280 | if (!p_schro_params->eos_signalled) { | |
281 | schro_encoder_end_of_stream(encoder); | |
282 | p_schro_params->eos_signalled = 1; | |
283 | } | |
284 | } else { | |
285 | /* Allocate frame data to schro input buffer. */ | |
286 | SchroFrame *in_frame = libschroedinger_frame_from_data(avctx, frame); | |
287 | /* Load next frame. */ | |
288 | schro_encoder_push_frame(encoder, in_frame); | |
289 | } | |
290 | ||
291 | if (p_schro_params->eos_pulled) | |
292 | go = 0; | |
293 | ||
294 | /* Now check to see if we have any output from the encoder. */ | |
295 | while (go) { | |
296 | int err; | |
297 | SchroStateEnum state; | |
298 | state = schro_encoder_wait(encoder); | |
299 | switch (state) { | |
300 | case SCHRO_STATE_HAVE_BUFFER: | |
301 | case SCHRO_STATE_END_OF_STREAM: | |
302 | enc_buf = schro_encoder_pull(encoder, &presentation_frame); | |
303 | if (enc_buf->length <= 0) | |
304 | return AVERROR_BUG; | |
305 | parse_code = enc_buf->data[4]; | |
306 | ||
307 | /* All non-frame data is prepended to actual frame data to | |
308 | * be able to set the pts correctly. So we don't write data | |
309 | * to the frame output queue until we actually have a frame | |
310 | */ | |
311 | if ((err = av_reallocp(&p_schro_params->enc_buf, | |
312 | p_schro_params->enc_buf_size + | |
313 | enc_buf->length)) < 0) { | |
314 | p_schro_params->enc_buf_size = 0; | |
315 | return err; | |
316 | } | |
317 | ||
318 | memcpy(p_schro_params->enc_buf + p_schro_params->enc_buf_size, | |
319 | enc_buf->data, enc_buf->length); | |
320 | p_schro_params->enc_buf_size += enc_buf->length; | |
321 | ||
322 | ||
323 | if (state == SCHRO_STATE_END_OF_STREAM) { | |
324 | p_schro_params->eos_pulled = 1; | |
325 | go = 0; | |
326 | } | |
327 | ||
328 | if (!SCHRO_PARSE_CODE_IS_PICTURE(parse_code)) { | |
329 | schro_buffer_unref(enc_buf); | |
330 | break; | |
331 | } | |
332 | ||
333 | /* Create output frame. */ | |
334 | p_frame_output = av_mallocz(sizeof(FFSchroEncodedFrame)); | |
335 | /* Set output data. */ | |
336 | p_frame_output->size = p_schro_params->enc_buf_size; | |
337 | p_frame_output->p_encbuf = p_schro_params->enc_buf; | |
338 | if (SCHRO_PARSE_CODE_IS_INTRA(parse_code) && | |
339 | SCHRO_PARSE_CODE_IS_REFERENCE(parse_code)) | |
340 | p_frame_output->key_frame = 1; | |
341 | ||
342 | /* Parse the coded frame number from the bitstream. Bytes 14 | |
343 | * through 17 represesent the frame number. */ | |
344 | p_frame_output->frame_num = AV_RB32(enc_buf->data + 13); | |
345 | ||
346 | ff_schro_queue_push_back(&p_schro_params->enc_frame_queue, | |
347 | p_frame_output); | |
348 | p_schro_params->enc_buf_size = 0; | |
349 | p_schro_params->enc_buf = NULL; | |
350 | ||
351 | schro_buffer_unref(enc_buf); | |
352 | ||
353 | break; | |
354 | ||
355 | case SCHRO_STATE_NEED_FRAME: | |
356 | go = 0; | |
357 | break; | |
358 | ||
359 | case SCHRO_STATE_AGAIN: | |
360 | break; | |
361 | ||
362 | default: | |
363 | av_log(avctx, AV_LOG_ERROR, "Unknown Schro Encoder state\n"); | |
364 | return -1; | |
365 | } | |
366 | } | |
367 | ||
368 | /* Copy 'next' frame in queue. */ | |
369 | ||
370 | if (p_schro_params->enc_frame_queue.size == 1 && | |
371 | p_schro_params->eos_pulled) | |
372 | last_frame_in_sequence = 1; | |
373 | ||
374 | p_frame_output = ff_schro_queue_pop(&p_schro_params->enc_frame_queue); | |
375 | ||
376 | if (!p_frame_output) | |
377 | return 0; | |
378 | ||
379 | pkt_size = p_frame_output->size; | |
380 | if (last_frame_in_sequence && p_schro_params->enc_buf_size > 0) | |
381 | pkt_size += p_schro_params->enc_buf_size; | |
382 | if ((ret = ff_alloc_packet2(avctx, pkt, pkt_size)) < 0) | |
383 | goto error; | |
384 | ||
385 | memcpy(pkt->data, p_frame_output->p_encbuf, p_frame_output->size); | |
386 | avctx->coded_frame->key_frame = p_frame_output->key_frame; | |
387 | /* Use the frame number of the encoded frame as the pts. It is OK to | |
388 | * do so since Dirac is a constant frame rate codec. It expects input | |
389 | * to be of constant frame rate. */ | |
390 | pkt->pts = | |
391 | avctx->coded_frame->pts = p_frame_output->frame_num; | |
392 | pkt->dts = p_schro_params->dts++; | |
393 | enc_size = p_frame_output->size; | |
394 | ||
395 | /* Append the end of sequence information to the last frame in the | |
396 | * sequence. */ | |
397 | if (last_frame_in_sequence && p_schro_params->enc_buf_size > 0) { | |
398 | memcpy(pkt->data + enc_size, p_schro_params->enc_buf, | |
399 | p_schro_params->enc_buf_size); | |
400 | enc_size += p_schro_params->enc_buf_size; | |
401 | av_freep(&p_schro_params->enc_buf); | |
402 | p_schro_params->enc_buf_size = 0; | |
403 | } | |
404 | ||
405 | if (p_frame_output->key_frame) | |
406 | pkt->flags |= AV_PKT_FLAG_KEY; | |
407 | *got_packet = 1; | |
408 | ||
409 | error: | |
410 | /* free frame */ | |
411 | libschroedinger_free_frame(p_frame_output); | |
412 | return ret; | |
413 | } | |
414 | ||
415 | ||
416 | static int libschroedinger_encode_close(AVCodecContext *avctx) | |
417 | { | |
418 | SchroEncoderParams *p_schro_params = avctx->priv_data; | |
419 | ||
420 | /* Close the encoder. */ | |
421 | schro_encoder_free(p_schro_params->encoder); | |
422 | ||
423 | /* Free data in the output frame queue. */ | |
424 | ff_schro_queue_free(&p_schro_params->enc_frame_queue, | |
425 | libschroedinger_free_frame); | |
426 | ||
427 | ||
428 | /* Free the encoder buffer. */ | |
429 | if (p_schro_params->enc_buf_size) | |
430 | av_freep(&p_schro_params->enc_buf); | |
431 | ||
432 | /* Free the video format structure. */ | |
433 | av_freep(&p_schro_params->format); | |
434 | ||
435 | av_frame_free(&avctx->coded_frame); | |
436 | ||
437 | return 0; | |
438 | } | |
439 | ||
440 | ||
441 | AVCodec ff_libschroedinger_encoder = { | |
442 | .name = "libschroedinger", | |
443 | .long_name = NULL_IF_CONFIG_SMALL("libschroedinger Dirac 2.2"), | |
444 | .type = AVMEDIA_TYPE_VIDEO, | |
445 | .id = AV_CODEC_ID_DIRAC, | |
446 | .priv_data_size = sizeof(SchroEncoderParams), | |
447 | .init = libschroedinger_encode_init, | |
448 | .encode2 = libschroedinger_encode_frame, | |
449 | .close = libschroedinger_encode_close, | |
450 | .capabilities = CODEC_CAP_DELAY, | |
451 | .pix_fmts = (const enum AVPixelFormat[]){ | |
452 | AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_NONE | |
453 | }, | |
454 | }; |