Libav
|
00001 /* 00002 * DVD subtitle decoding for ffmpeg 00003 * Copyright (c) 2005 Fabrice Bellard 00004 * 00005 * This file is part of FFmpeg. 00006 * 00007 * FFmpeg is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * FFmpeg is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with FFmpeg; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00020 */ 00021 00022 #include "libavutil/intreadwrite.h" 00023 #include "avcodec.h" 00024 00025 /* parser definition */ 00026 typedef struct DVDSubParseContext { 00027 uint8_t *packet; 00028 int packet_len; 00029 int packet_index; 00030 } DVDSubParseContext; 00031 00032 static av_cold int dvdsub_parse_init(AVCodecParserContext *s) 00033 { 00034 return 0; 00035 } 00036 00037 static int dvdsub_parse(AVCodecParserContext *s, 00038 AVCodecContext *avctx, 00039 const uint8_t **poutbuf, int *poutbuf_size, 00040 const uint8_t *buf, int buf_size) 00041 { 00042 DVDSubParseContext *pc = s->priv_data; 00043 00044 if (pc->packet_index == 0) { 00045 if (buf_size < 2) 00046 return 0; 00047 pc->packet_len = AV_RB16(buf); 00048 if (pc->packet_len == 0) /* HD-DVD subpicture packet */ 00049 pc->packet_len = AV_RB32(buf+2); 00050 av_freep(&pc->packet); 00051 pc->packet = av_malloc(pc->packet_len); 00052 } 00053 if (pc->packet) { 00054 if (pc->packet_index + buf_size <= pc->packet_len) { 00055 memcpy(pc->packet + pc->packet_index, buf, buf_size); 00056 pc->packet_index += buf_size; 00057 if (pc->packet_index >= pc->packet_len) { 00058 *poutbuf = pc->packet; 00059 *poutbuf_size = pc->packet_len; 00060 pc->packet_index = 0; 00061 return buf_size; 00062 } 00063 } else { 00064 /* erroneous size */ 00065 pc->packet_index = 0; 00066 } 00067 } 00068 *poutbuf = NULL; 00069 *poutbuf_size = 0; 00070 return buf_size; 00071 } 00072 00073 static av_cold void dvdsub_parse_close(AVCodecParserContext *s) 00074 { 00075 DVDSubParseContext *pc = s->priv_data; 00076 av_freep(&pc->packet); 00077 } 00078 00079 AVCodecParser dvdsub_parser = { 00080 { CODEC_ID_DVD_SUBTITLE }, 00081 sizeof(DVDSubParseContext), 00082 dvdsub_parse_init, 00083 dvdsub_parse, 00084 dvdsub_parse_close, 00085 };