WinGui: Fix another instance of the Caliburn vs Json.net sillyness where objects...
[HandBrake.git] / libhb / decpgssub.c
blob4f60f572212882be2dc0cc66fc784b1f403e829d
1 /* decpgssub.c
3 Copyright (c) 2003-2015 HandBrake Team
4 This file is part of the HandBrake source code
5 Homepage: <http://handbrake.fr/>.
6 It may be used under the terms of the GNU General Public License v2.
7 For full terms see the file COPYING file or visit http://www.gnu.org/licenses/gpl-2.0.html
8 */
10 #include "hb.h"
11 #include "hbffmpeg.h"
13 struct hb_work_private_s
15 AVCodecContext * context;
16 hb_job_t * job;
17 // For PGS subs, when doing passthru, we don't know if we need a
18 // packet until we have processed several packets. So we cache
19 // all the packets we see until libav returns a subtitle with
20 // the information we need.
21 hb_buffer_t * list_pass_buffer;
22 hb_buffer_t * last_pass_buffer;
23 // It is possible for multiple subtitles to be enncapsulated in
24 // one packet. This won't happen for PGS subs, but may for other
25 // types of subtitles. Since I plan to generalize this code to handle
26 // other than PGS, we will need to keep a list of all subtitles seen
27 // while parsing an input packet.
28 hb_buffer_t * list_buffer;
29 hb_buffer_t * last_buffer;
30 // XXX: we may occasionally see subtitles with broken timestamps
31 // while this should really get fixed elsewhere,
32 // dropping subtitles should be avoided as much as possible
33 int64_t last_pts;
34 // for PGS subs, we need to pass 'empty' subtitles through (they clear the
35 // display) - when doing forced-only extraction, only pass empty subtitles
36 // through if we've seen a forced sub and haven't seen any empty sub since
37 uint8_t seen_forced_sub;
38 // if we start encoding partway through the source, we may encounter empty
39 // subtitles before we see any actual subtitle content - discard them
40 uint8_t discard_subtitle;
43 static int decsubInit( hb_work_object_t * w, hb_job_t * job )
45 AVCodec *codec = avcodec_find_decoder( AV_CODEC_ID_HDMV_PGS_SUBTITLE );
46 AVCodecContext *context = avcodec_alloc_context3( codec );
47 context->codec = codec;
49 hb_work_private_t * pv;
50 pv = calloc( 1, sizeof( hb_work_private_t ) );
51 w->private_data = pv;
53 pv->discard_subtitle = 1;
54 pv->seen_forced_sub = 0;
55 pv->last_pts = 0;
56 pv->context = context;
57 pv->job = job;
59 // Set decoder opts...
60 AVDictionary * av_opts = NULL;
61 // e.g. av_dict_set( &av_opts, "refcounted_frames", "1", 0 );
63 if (hb_avcodec_open(pv->context, codec, &av_opts, 0))
65 av_dict_free( &av_opts );
66 hb_log("decsubInit: avcodec_open failed");
67 return 1;
69 av_dict_free( &av_opts );
72 return 0;
75 static void make_empty_pgs( hb_buffer_t * buf )
77 hb_buffer_t * b = buf;
78 uint8_t done = 0;
80 // Each buffer is composed of 1 or more segments.
81 // Segment header is:
82 // type - 1 byte
83 // length - 2 bytes
84 // We want to modify the presentation segment which is type 0x16
86 // Note that every pgs display set is required to have a presentation
87 // segment, so we will only have to look at one display set.
88 while ( b && !done )
90 int ii = 0;
92 while (ii + 3 <= b->size)
94 uint8_t type;
95 int len;
96 int segment_len_pos;
98 type = b->data[ii++];
99 segment_len_pos = ii;
100 len = ((int)b->data[ii] << 8) + b->data[ii+1];
101 ii += 2;
103 if (type == 0x16 && ii + len <= b->size)
105 int obj_count;
106 int kk, jj = ii;
107 int obj_start;
109 // Skip
110 // video descriptor 5 bytes
111 // composition descriptor 3 bytes
112 // palette update flg 1 byte
113 // palette id ref 1 byte
114 jj += 10;
116 // Set number of composition objects to 0
117 obj_count = b->data[jj];
118 b->data[jj] = 0;
119 jj++;
120 obj_start = jj;
122 // And remove all the composition objects
123 for (kk = 0; kk < obj_count; kk++)
125 uint8_t crop;
127 crop = b->data[jj + 3];
128 // skip
129 // object id - 2 bytes
130 // window id - 1 byte
131 // object/forced flag - 1 byte
132 // x pos - 2 bytes
133 // y pos - 2 bytes
134 jj += 8;
135 if (crop & 0x80)
137 // skip
138 // crop x - 2 bytes
139 // crop y - 2 bytes
140 // crop w - 2 bytes
141 // crop h - 2 bytes
142 jj += 8;
145 if (jj < b->size)
147 memmove(b->data + obj_start, b->data + jj, b->size - jj);
149 b->size = obj_start + ( b->size - jj );
150 done = 1;
151 len = obj_start - (segment_len_pos + 2);
152 b->data[segment_len_pos] = len >> 8;
153 b->data[segment_len_pos+1] = len & 0xff;
154 break;
156 ii += len;
158 b = b->next;
162 static int decsubWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
163 hb_buffer_t ** buf_out )
165 hb_work_private_t * pv = w->private_data;
166 hb_buffer_t * in = *buf_in;
168 if (in->s.flags & HB_BUF_FLAG_EOF)
170 /* EOF on input stream - send it downstream & say that we're done */
171 if ( pv->list_buffer == NULL )
173 pv->list_buffer = pv->last_buffer = in;
175 else
177 pv->last_buffer->next = in;
179 *buf_in = NULL;
180 *buf_out = pv->list_buffer;
181 pv->list_buffer = NULL;
183 return HB_WORK_DONE;
186 if ( !pv->job->indepth_scan &&
187 w->subtitle->config.dest == PASSTHRUSUB &&
188 hb_subtitle_can_pass( PGSSUB, pv->job->mux ) )
190 // Append to buffer list. It will be sent to fifo after we determine
191 // if this is a packet we need.
192 if ( pv->list_pass_buffer == NULL )
194 pv->list_pass_buffer = pv->last_pass_buffer = in;
196 else
198 pv->last_pass_buffer->next = in;
199 pv->last_pass_buffer = in;
201 // We are keeping the buffer, so prevent the filter loop from
202 // deleting it.
203 *buf_in = NULL;
206 AVSubtitle subtitle;
207 memset( &subtitle, 0, sizeof(subtitle) );
209 AVPacket avp;
210 av_init_packet( &avp );
211 avp.data = in->data;
212 avp.size = in->size;
213 // libav wants pkt pts in AV_TIME_BASE units
214 if (in->s.start != AV_NOPTS_VALUE)
216 avp.pts = av_rescale(in->s.start, AV_TIME_BASE, 90000);
218 else
220 avp.pts = AV_NOPTS_VALUE;
223 int has_subtitle = 0;
227 int usedBytes = avcodec_decode_subtitle2( pv->context, &subtitle, &has_subtitle, &avp );
228 if (usedBytes < 0)
230 hb_log("unable to decode subtitle with %d bytes.", avp.size);
231 return HB_WORK_OK;
234 if (usedBytes <= avp.size)
236 avp.data += usedBytes;
237 avp.size -= usedBytes;
239 else
241 avp.size = 0;
244 /* Subtitles are "usable" if:
245 * 1. Libav returned a subtitle (has_subtitle) AND
246 * 2. we're not doing Foreign Audio Search (!pv->job->indepth_scan) AND
247 * 3. the sub is non-empty or we've seen one such sub before (!pv->discard_subtitle)
248 * For forced-only extraction, usable subtitles also need to:
249 * a. be forced (subtitle.rects[0]->flags & AV_SUBTITLE_FLAG_FORCED) OR
250 * b. follow a forced sub (pv->seen_forced_sub) */
251 uint8_t forced_sub = 0;
252 uint8_t useable_sub = 0;
253 uint8_t clear_subtitle = 0;
255 if (has_subtitle)
257 // subtitle statistics
258 if (subtitle.num_rects)
260 w->subtitle->hits++;
261 if (subtitle.rects[0]->flags & AV_SUBTITLE_FLAG_FORCED)
263 forced_sub = 1;
264 w->subtitle->forced_hits++;
267 else
269 clear_subtitle = 1;
271 // are we doing Foreign Audio Search?
272 if (!pv->job->indepth_scan)
274 // do we want to discard this subtitle?
275 pv->discard_subtitle = pv->discard_subtitle && clear_subtitle;
276 // do we need this subtitle?
277 useable_sub = (!pv->discard_subtitle &&
278 (!w->subtitle->config.force ||
279 forced_sub || pv->seen_forced_sub));
280 // do we need to create an empty subtitle?
281 if (w->subtitle->config.force &&
282 useable_sub && !forced_sub && !clear_subtitle)
284 // We are forced-only and need to output this subtitle, but
285 // it's neither forced nor empty.
287 // If passthru, create an empty subtitle.
288 // Also, flag an empty subtitle for subtitle RENDER.
289 make_empty_pgs(pv->list_pass_buffer);
290 clear_subtitle = 1;
292 // is the subtitle forced?
293 pv->seen_forced_sub = forced_sub;
297 if (useable_sub)
299 int64_t pts = AV_NOPTS_VALUE;
300 hb_buffer_t * out = NULL;
302 if (subtitle.pts != AV_NOPTS_VALUE)
304 pts = av_rescale(subtitle.pts, 90000, AV_TIME_BASE);
306 else
308 if (in->s.start >= 0)
310 pts = in->s.start;
312 else
314 // XXX: a broken pts will cause us to drop this subtitle,
315 // which is bad; use a default duration of 3 seconds
317 // A broken pts is only generated when a pgs packet
318 // occurs after a discontinuity and before the
319 // next audio or video packet which re-establishes
320 // timing (afaik).
321 pts = pv->last_pts + 3 * 90000LL;
322 hb_log("[warning] decpgssub: track %d, invalid PTS",
323 w->subtitle->out_track);
326 // work around broken timestamps
327 if (pts < pv->last_pts)
329 // XXX: this should only happen if the prevous pts
330 // was unknown and our 3 second default duration
331 // overshot the next pgs pts.
333 // assign a 1 second duration
334 pts = pv->last_pts + 1 * 90000LL;
335 hb_log("[warning] decpgssub: track %d, non-monotically increasing PTS",
336 w->subtitle->out_track);
338 pv->last_pts = pts;
340 if ( w->subtitle->config.dest == PASSTHRUSUB &&
341 hb_subtitle_can_pass( PGSSUB, pv->job->mux ) )
343 /* PGS subtitles are spread across multiple packets (1 per segment).
344 * In the MKV container, all segments are found in the same packet
345 * (this is expected by some devices, such as the WD TV Live).
346 * So if there are multiple packets, merge them. */
347 if (pv->list_pass_buffer->next == NULL)
349 // packets already merged (e.g. MKV sources)
350 out = pv->list_pass_buffer;
351 pv->list_pass_buffer = NULL;
353 else
355 int size = 0;
356 uint8_t * data;
357 hb_buffer_t * b;
359 b = pv->list_pass_buffer;
360 while (b != NULL)
362 size += b->size;
363 b = b->next;
366 out = hb_buffer_init( size );
367 data = out->data;
368 b = pv->list_pass_buffer;
369 while (b != NULL)
371 memcpy( data, b->data, b->size );
372 data += b->size;
373 b = b->next;
375 hb_buffer_close( &pv->list_pass_buffer );
377 out->s = in->s;
378 out->sequence = in->sequence;
380 out->s.frametype = HB_FRAME_SUBTITLE;
381 out->s.renderOffset = AV_NOPTS_VALUE;
382 out->s.stop = AV_NOPTS_VALUE;
383 out->s.start = pts;
385 else
387 if (!clear_subtitle)
389 unsigned ii, x0, y0, x1, y1, w, h;
391 x0 = subtitle.rects[0]->x;
392 y0 = subtitle.rects[0]->y;
393 x1 = subtitle.rects[0]->x + subtitle.rects[0]->w;
394 y1 = subtitle.rects[0]->y + subtitle.rects[0]->h;
396 // First, find total bounding rectangle
397 for (ii = 1; ii < subtitle.num_rects; ii++)
399 if (subtitle.rects[ii]->x < x0)
400 x0 = subtitle.rects[ii]->x;
401 if (subtitle.rects[ii]->y < y0)
402 y0 = subtitle.rects[ii]->y;
403 if (subtitle.rects[ii]->x + subtitle.rects[ii]->w > x1)
404 x1 = subtitle.rects[ii]->x + subtitle.rects[ii]->w;
405 if (subtitle.rects[ii]->y + subtitle.rects[ii]->h > y1)
406 y1 = subtitle.rects[ii]->y + subtitle.rects[ii]->h;
408 w = x1 - x0;
409 h = y1 - y0;
411 out = hb_frame_buffer_init(AV_PIX_FMT_YUVA420P, w, h);
412 memset(out->data, 0, out->size);
414 out->s.frametype = HB_FRAME_SUBTITLE;
415 out->s.id = in->s.id;
416 out->sequence = in->sequence;
417 out->s.start = pts;
418 out->s.stop = AV_NOPTS_VALUE;
419 out->s.renderOffset = AV_NOPTS_VALUE;
420 out->f.x = x0;
421 out->f.y = y0;
422 for (ii = 0; ii < subtitle.num_rects; ii++)
424 AVSubtitleRect *rect = subtitle.rects[ii];
426 int off_x = rect->x - x0;
427 int off_y = rect->y - y0;
428 uint8_t *lum = out->plane[0].data;
429 uint8_t *chromaU = out->plane[1].data;
430 uint8_t *chromaV = out->plane[2].data;
431 uint8_t *alpha = out->plane[3].data;
433 lum += off_y * out->plane[0].stride + off_x;
434 alpha += off_y * out->plane[3].stride + off_x;
435 chromaU += (off_y >> 1) * out->plane[1].stride + (off_x >> 1);
436 chromaV += (off_y >> 1) * out->plane[2].stride + (off_x >> 1);
438 int xx, yy;
439 for (yy = 0; yy < rect->h; yy++)
441 for (xx = 0; xx < rect->w; xx++)
443 uint32_t argb, yuv;
444 int pixel;
445 uint8_t color;
447 pixel = yy * rect->w + xx;
448 color = rect->pict.data[0][pixel];
449 argb = ((uint32_t*)rect->pict.data[1])[color];
450 yuv = hb_rgb2yuv(argb);
452 lum[xx] = (yuv >> 16) & 0xff;
453 alpha[xx] = (argb >> 24) & 0xff;
454 if ((xx & 1) == 0 && (yy & 1) == 0)
456 chromaV[xx>>1] = (yuv >> 8) & 0xff;
457 chromaU[xx>>1] = yuv & 0xff;
460 lum += out->plane[0].stride;
461 if ((yy & 1) == 0)
463 chromaU += out->plane[1].stride;
464 chromaV += out->plane[2].stride;
466 alpha += out->plane[3].stride;
469 if ( pv->list_buffer == NULL )
471 pv->list_buffer = pv->last_buffer = out;
473 else
475 pv->last_buffer->next = out;
476 pv->last_buffer = out;
478 out = NULL;
480 else
482 out = hb_buffer_init( 1 );
484 out->s.frametype = HB_FRAME_SUBTITLE;
485 out->s.id = in->s.id;
486 out->s.start = pts;
487 out->s.stop = pts;
488 out->f.x = 0;
489 out->f.y = 0;
490 out->f.width = 0;
491 out->f.height = 0;
494 if ( pv->list_buffer == NULL )
496 pv->list_buffer = pv->last_buffer = out;
498 else
500 pv->last_buffer->next = out;
502 while (pv->last_buffer && pv->last_buffer->next)
504 pv->last_buffer = pv->last_buffer->next;
507 else if ( has_subtitle )
509 hb_buffer_close( &pv->list_pass_buffer );
510 pv->list_pass_buffer = NULL;
512 if ( has_subtitle )
514 avsubtitle_free(&subtitle);
516 } while (avp.size > 0);
518 *buf_out = pv->list_buffer;
519 pv->list_buffer = NULL;
520 return HB_WORK_OK;
523 static void decsubClose( hb_work_object_t * w )
525 hb_work_private_t * pv = w->private_data;
526 avcodec_flush_buffers( pv->context );
527 avcodec_close( pv->context );
530 hb_work_object_t hb_decpgssub =
532 WORK_DECPGSSUB,
533 "PGS decoder",
534 decsubInit,
535 decsubWork,
536 decsubClose