| OLD | NEW |
| 1 /* | 1 /* |
| 2 * DVB subtitle decoding for ffmpeg | 2 * DVB subtitle decoding for ffmpeg |
| 3 * Copyright (c) 2005 Ian Caulfield | 3 * Copyright (c) 2005 Ian Caulfield |
| 4 * | 4 * |
| 5 * This file is part of FFmpeg. | 5 * This file is part of FFmpeg. |
| 6 * | 6 * |
| 7 * FFmpeg is free software; you can redistribute it and/or | 7 * FFmpeg is free software; you can redistribute it and/or |
| 8 * modify it under the terms of the GNU Lesser General Public | 8 * modify it under the terms of the GNU Lesser General Public |
| 9 * License as published by the Free Software Foundation; either | 9 * License as published by the Free Software Foundation; either |
| 10 * version 2.1 of the License, or (at your option) any later version. | 10 * version 2.1 of the License, or (at your option) any later version. |
| 11 * | 11 * |
| 12 * FFmpeg is distributed in the hope that it will be useful, | 12 * FFmpeg is distributed in the hope that it will be useful, |
| 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 15 * Lesser General Public License for more details. | 15 * Lesser General Public License for more details. |
| 16 * | 16 * |
| 17 * You should have received a copy of the GNU Lesser General Public | 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 | 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 | 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 20 */ | 20 */ |
| 21 #include "avcodec.h" | 21 #include "avcodec.h" |
| 22 #include "dsputil.h" | 22 #include "dsputil.h" |
| 23 #include "get_bits.h" | 23 #include "get_bits.h" |
| 24 #include "colorspace.h" | 24 #include "colorspace.h" |
| 25 #include "bytestream.h" |
| 25 | 26 |
| 26 //#define DEBUG | 27 //#define DEBUG |
| 27 //#define DEBUG_PACKET_CONTENTS | 28 //#define DEBUG_PACKET_CONTENTS |
| 28 //#define DEBUG_SAVE_IMAGES | 29 //#define DEBUG_SAVE_IMAGES |
| 29 | 30 |
| 30 #define DVBSUB_PAGE_SEGMENT 0x10 | 31 #define DVBSUB_PAGE_SEGMENT 0x10 |
| 31 #define DVBSUB_REGION_SEGMENT 0x11 | 32 #define DVBSUB_REGION_SEGMENT 0x11 |
| 32 #define DVBSUB_CLUT_SEGMENT 0x12 | 33 #define DVBSUB_CLUT_SEGMENT 0x12 |
| 33 #define DVBSUB_OBJECT_SEGMENT 0x13 | 34 #define DVBSUB_OBJECT_SEGMENT 0x13 |
| 35 #define DVBSUB_DISPLAYDEFINITION_SEGMENT 0x14 |
| 34 #define DVBSUB_DISPLAY_SEGMENT 0x80 | 36 #define DVBSUB_DISPLAY_SEGMENT 0x80 |
| 35 | 37 |
| 36 #define cm (ff_cropTbl + MAX_NEG_CROP) | 38 #define cm (ff_cropTbl + MAX_NEG_CROP) |
| 37 | 39 |
| 38 #ifdef DEBUG_SAVE_IMAGES | 40 #ifdef DEBUG_SAVE_IMAGES |
| 39 #undef fprintf | 41 #undef fprintf |
| 40 #if 0 | 42 #if 0 |
| 41 static void png_save(const char *filename, uint8_t *bitmap, int w, int h, | 43 static void png_save(const char *filename, uint8_t *bitmap, int w, int h, |
| 42 uint32_t *rgba_palette) | 44 uint32_t *rgba_palette) |
| 43 { | 45 { |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 209 int bgcolor; | 211 int bgcolor; |
| 210 | 212 |
| 211 uint8_t *pbuf; | 213 uint8_t *pbuf; |
| 212 int buf_size; | 214 int buf_size; |
| 213 | 215 |
| 214 DVBSubObjectDisplay *display_list; | 216 DVBSubObjectDisplay *display_list; |
| 215 | 217 |
| 216 struct DVBSubRegion *next; | 218 struct DVBSubRegion *next; |
| 217 } DVBSubRegion; | 219 } DVBSubRegion; |
| 218 | 220 |
| 221 typedef struct DVBSubDisplayDefinition { |
| 222 int version; |
| 223 |
| 224 int x; |
| 225 int y; |
| 226 int width; |
| 227 int height; |
| 228 } DVBSubDisplayDefinition; |
| 229 |
| 219 typedef struct DVBSubContext { | 230 typedef struct DVBSubContext { |
| 220 int composition_id; | 231 int composition_id; |
| 221 int ancillary_id; | 232 int ancillary_id; |
| 222 | 233 |
| 223 int time_out; | 234 int time_out; |
| 224 DVBSubRegion *region_list; | 235 DVBSubRegion *region_list; |
| 225 DVBSubCLUT *clut_list; | 236 DVBSubCLUT *clut_list; |
| 226 DVBSubObject *object_list; | 237 DVBSubObject *object_list; |
| 227 | 238 |
| 228 int display_list_size; | 239 int display_list_size; |
| 229 DVBSubRegionDisplay *display_list; | 240 DVBSubRegionDisplay *display_list; |
| 241 DVBSubDisplayDefinition *display_definition; |
| 230 } DVBSubContext; | 242 } DVBSubContext; |
| 231 | 243 |
| 232 | 244 |
| 233 static DVBSubObject* get_object(DVBSubContext *ctx, int object_id) | 245 static DVBSubObject* get_object(DVBSubContext *ctx, int object_id) |
| 234 { | 246 { |
| 235 DVBSubObject *ptr = ctx->object_list; | 247 DVBSubObject *ptr = ctx->object_list; |
| 236 | 248 |
| 237 while (ptr && ptr->id != object_id) { | 249 while (ptr && ptr->id != object_id) { |
| 238 ptr = ptr->next; | 250 ptr = ptr->next; |
| 239 } | 251 } |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 327 } | 339 } |
| 328 | 340 |
| 329 while (ctx->clut_list) { | 341 while (ctx->clut_list) { |
| 330 clut = ctx->clut_list; | 342 clut = ctx->clut_list; |
| 331 | 343 |
| 332 ctx->clut_list = clut->next; | 344 ctx->clut_list = clut->next; |
| 333 | 345 |
| 334 av_free(clut); | 346 av_free(clut); |
| 335 } | 347 } |
| 336 | 348 |
| 349 av_freep(&ctx->display_definition); |
| 350 |
| 337 /* Should already be null */ | 351 /* Should already be null */ |
| 338 if (ctx->object_list) | 352 if (ctx->object_list) |
| 339 av_log(0, AV_LOG_ERROR, "Memory deallocation error!\n"); | 353 av_log(0, AV_LOG_ERROR, "Memory deallocation error!\n"); |
| 340 } | 354 } |
| 341 | 355 |
| 342 static av_cold int dvbsub_init_decoder(AVCodecContext *avctx) | 356 static av_cold int dvbsub_init_decoder(AVCodecContext *avctx) |
| 343 { | 357 { |
| 344 int i, r, g, b, a = 0; | 358 int i, r, g, b, a = 0; |
| 345 DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data; | 359 DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data; |
| 346 | 360 |
| (...skipping 900 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1247 | 1261 |
| 1248 png_save2(filename, pbuf, width, height); | 1262 png_save2(filename, pbuf, width, height); |
| 1249 | 1263 |
| 1250 av_free(pbuf); | 1264 av_free(pbuf); |
| 1251 } | 1265 } |
| 1252 | 1266 |
| 1253 fileno_index++; | 1267 fileno_index++; |
| 1254 } | 1268 } |
| 1255 #endif | 1269 #endif |
| 1256 | 1270 |
| 1271 static void dvbsub_parse_display_definition_segment(AVCodecContext *avctx, |
| 1272 const uint8_t *buf, |
| 1273 int buf_size) |
| 1274 { |
| 1275 DVBSubContext *ctx = avctx->priv_data; |
| 1276 DVBSubDisplayDefinition *display_def = ctx->display_definition; |
| 1277 int dds_version, info_byte; |
| 1278 |
| 1279 if (buf_size < 5) |
| 1280 return; |
| 1281 |
| 1282 info_byte = bytestream_get_byte(&buf); |
| 1283 dds_version = info_byte >> 4; |
| 1284 if (display_def && display_def->version == dds_version) |
| 1285 return; // already have this display definition version |
| 1286 |
| 1287 if (!display_def) { |
| 1288 display_def = av_mallocz(sizeof(*display_def)); |
| 1289 ctx->display_definition = display_def; |
| 1290 } |
| 1291 if (!display_def) |
| 1292 return; |
| 1293 |
| 1294 display_def->version = dds_version; |
| 1295 display_def->x = 0; |
| 1296 display_def->y = 0; |
| 1297 display_def->width = bytestream_get_be16(&buf) + 1; |
| 1298 display_def->height = bytestream_get_be16(&buf) + 1; |
| 1299 |
| 1300 if (buf_size < 13) |
| 1301 return; |
| 1302 |
| 1303 if (info_byte & 1<<3) { // display_window_flag |
| 1304 display_def->x = bytestream_get_be16(&buf); |
| 1305 display_def->y = bytestream_get_be16(&buf); |
| 1306 display_def->width = bytestream_get_be16(&buf) - display_def->x + 1; |
| 1307 display_def->height = bytestream_get_be16(&buf) - display_def->y + 1; |
| 1308 } |
| 1309 } |
| 1310 |
| 1257 static int dvbsub_display_end_segment(AVCodecContext *avctx, const uint8_t *buf, | 1311 static int dvbsub_display_end_segment(AVCodecContext *avctx, const uint8_t *buf, |
| 1258 int buf_size, AVSubtitle *sub) | 1312 int buf_size, AVSubtitle *sub) |
| 1259 { | 1313 { |
| 1260 DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data; | 1314 DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data; |
| 1315 DVBSubDisplayDefinition *display_def = ctx->display_definition; |
| 1261 | 1316 |
| 1262 DVBSubRegion *region; | 1317 DVBSubRegion *region; |
| 1263 DVBSubRegionDisplay *display; | 1318 DVBSubRegionDisplay *display; |
| 1264 AVSubtitleRect *rect; | 1319 AVSubtitleRect *rect; |
| 1265 DVBSubCLUT *clut; | 1320 DVBSubCLUT *clut; |
| 1266 uint32_t *clut_table; | 1321 uint32_t *clut_table; |
| 1267 int i; | 1322 int i; |
| 1323 int offset_x=0, offset_y=0; |
| 1268 | 1324 |
| 1269 sub->rects = NULL; | 1325 sub->rects = NULL; |
| 1270 sub->start_display_time = 0; | 1326 sub->start_display_time = 0; |
| 1271 sub->end_display_time = ctx->time_out * 1000; | 1327 sub->end_display_time = ctx->time_out * 1000; |
| 1272 sub->format = 0; | 1328 sub->format = 0; |
| 1273 | 1329 |
| 1330 if (display_def) { |
| 1331 offset_x = display_def->x; |
| 1332 offset_y = display_def->y; |
| 1333 } |
| 1334 |
| 1274 sub->num_rects = ctx->display_list_size; | 1335 sub->num_rects = ctx->display_list_size; |
| 1275 | 1336 |
| 1276 if (sub->num_rects > 0){ | 1337 if (sub->num_rects > 0){ |
| 1277 sub->rects = av_mallocz(sizeof(*sub->rects) * sub->num_rects); | 1338 sub->rects = av_mallocz(sizeof(*sub->rects) * sub->num_rects); |
| 1278 for(i=0; i<sub->num_rects; i++) | 1339 for(i=0; i<sub->num_rects; i++) |
| 1279 sub->rects[i] = av_mallocz(sizeof(*sub->rects[i])); | 1340 sub->rects[i] = av_mallocz(sizeof(*sub->rects[i])); |
| 1280 } | 1341 } |
| 1281 | 1342 |
| 1282 i = 0; | 1343 i = 0; |
| 1283 | 1344 |
| 1284 for (display = ctx->display_list; display; display = display->next) { | 1345 for (display = ctx->display_list; display; display = display->next) { |
| 1285 region = get_region(ctx, display->region_id); | 1346 region = get_region(ctx, display->region_id); |
| 1286 rect = sub->rects[i]; | 1347 rect = sub->rects[i]; |
| 1287 | 1348 |
| 1288 if (!region) | 1349 if (!region) |
| 1289 continue; | 1350 continue; |
| 1290 | 1351 |
| 1291 rect->x = display->x_pos; | 1352 rect->x = display->x_pos + offset_x; |
| 1292 rect->y = display->y_pos; | 1353 rect->y = display->y_pos + offset_y; |
| 1293 rect->w = region->width; | 1354 rect->w = region->width; |
| 1294 rect->h = region->height; | 1355 rect->h = region->height; |
| 1295 rect->nb_colors = 16; | 1356 rect->nb_colors = 16; |
| 1296 rect->type = SUBTITLE_BITMAP; | 1357 rect->type = SUBTITLE_BITMAP; |
| 1297 rect->pict.linesize[0] = region->width; | 1358 rect->pict.linesize[0] = region->width; |
| 1298 | 1359 |
| 1299 clut = get_clut(ctx, region->clut); | 1360 clut = get_clut(ctx, region->clut); |
| 1300 | 1361 |
| 1301 if (!clut) | 1362 if (!clut) |
| 1302 clut = &default_clut; | 1363 clut = &default_clut; |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1382 break; | 1443 break; |
| 1383 case DVBSUB_REGION_SEGMENT: | 1444 case DVBSUB_REGION_SEGMENT: |
| 1384 dvbsub_parse_region_segment(avctx, p, segment_length); | 1445 dvbsub_parse_region_segment(avctx, p, segment_length); |
| 1385 break; | 1446 break; |
| 1386 case DVBSUB_CLUT_SEGMENT: | 1447 case DVBSUB_CLUT_SEGMENT: |
| 1387 dvbsub_parse_clut_segment(avctx, p, segment_length); | 1448 dvbsub_parse_clut_segment(avctx, p, segment_length); |
| 1388 break; | 1449 break; |
| 1389 case DVBSUB_OBJECT_SEGMENT: | 1450 case DVBSUB_OBJECT_SEGMENT: |
| 1390 dvbsub_parse_object_segment(avctx, p, segment_length); | 1451 dvbsub_parse_object_segment(avctx, p, segment_length); |
| 1391 break; | 1452 break; |
| 1453 case DVBSUB_DISPLAYDEFINITION_SEGMENT: |
| 1454 dvbsub_parse_display_definition_segment(avctx, p, segment_length
); |
| 1392 case DVBSUB_DISPLAY_SEGMENT: | 1455 case DVBSUB_DISPLAY_SEGMENT: |
| 1393 *data_size = dvbsub_display_end_segment(avctx, p, segment_length
, sub); | 1456 *data_size = dvbsub_display_end_segment(avctx, p, segment_length
, sub); |
| 1394 break; | 1457 break; |
| 1395 default: | 1458 default: |
| 1396 dprintf(avctx, "Subtitling segment type 0x%x, page id %d, length
%d\n", | 1459 dprintf(avctx, "Subtitling segment type 0x%x, page id %d, length
%d\n", |
| 1397 segment_type, page_id, segment_length); | 1460 segment_type, page_id, segment_length); |
| 1398 break; | 1461 break; |
| 1399 } | 1462 } |
| 1400 } | 1463 } |
| 1401 | 1464 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1415 "dvbsub", | 1478 "dvbsub", |
| 1416 AVMEDIA_TYPE_SUBTITLE, | 1479 AVMEDIA_TYPE_SUBTITLE, |
| 1417 CODEC_ID_DVB_SUBTITLE, | 1480 CODEC_ID_DVB_SUBTITLE, |
| 1418 sizeof(DVBSubContext), | 1481 sizeof(DVBSubContext), |
| 1419 dvbsub_init_decoder, | 1482 dvbsub_init_decoder, |
| 1420 NULL, | 1483 NULL, |
| 1421 dvbsub_close_decoder, | 1484 dvbsub_close_decoder, |
| 1422 dvbsub_decode, | 1485 dvbsub_decode, |
| 1423 .long_name = NULL_IF_CONFIG_SMALL("DVB subtitles"), | 1486 .long_name = NULL_IF_CONFIG_SMALL("DVB subtitles"), |
| 1424 }; | 1487 }; |
| OLD | NEW |