yading@11: /* yading@11: * SAUCE header parser yading@11: * Copyright (c) 2010 Peter Ross yading@11: * yading@11: * This file is part of FFmpeg. yading@11: * yading@11: * FFmpeg is free software; you can redistribute it and/or yading@11: * modify it under the terms of the GNU Lesser General Public yading@11: * License as published by the Free Software Foundation; either yading@11: * version 2.1 of the License, or (at your option) any later version. yading@11: * yading@11: * FFmpeg is distributed in the hope that it will be useful, yading@11: * but WITHOUT ANY WARRANTY; without even the implied warranty of yading@11: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU yading@11: * Lesser General Public License for more details. yading@11: * yading@11: * You should have received a copy of the GNU Lesser General Public yading@11: * License along with FFmpeg; if not, write to the Free Software yading@11: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA yading@11: */ yading@11: yading@11: /** yading@11: * @file yading@11: * SAUCE header parser yading@11: */ yading@11: yading@11: #include "libavutil/intreadwrite.h" yading@11: #include "libavutil/dict.h" yading@11: #include "avformat.h" yading@11: #include "sauce.h" yading@11: yading@11: int ff_sauce_read(AVFormatContext *avctx, uint64_t *fsize, int *got_width, int get_height) yading@11: { yading@11: AVIOContext *pb = avctx->pb; yading@11: char buf[36]; yading@11: int datatype, filetype, t1, t2, nb_comments; yading@11: uint64_t start_pos = avio_size(pb) - 128; yading@11: yading@11: avio_seek(pb, start_pos, SEEK_SET); yading@11: if (avio_read(pb, buf, 7) != 7) yading@11: return -1; yading@11: if (memcmp(buf, "SAUCE00", 7)) yading@11: return -1; yading@11: yading@11: #define GET_SAUCE_META(name,size) \ yading@11: if (avio_read(pb, buf, size) == size && buf[0]) { \ yading@11: buf[size] = 0; \ yading@11: av_dict_set(&avctx->metadata, name, buf, 0); \ yading@11: } yading@11: yading@11: GET_SAUCE_META("title", 35) yading@11: GET_SAUCE_META("artist", 20) yading@11: GET_SAUCE_META("publisher", 20) yading@11: GET_SAUCE_META("date", 8) yading@11: avio_skip(pb, 4); yading@11: datatype = avio_r8(pb); yading@11: filetype = avio_r8(pb); yading@11: t1 = avio_rl16(pb); yading@11: t2 = avio_rl16(pb); yading@11: nb_comments = avio_r8(pb); yading@11: avio_skip(pb, 1); /* flags */ yading@11: avio_skip(pb, 4); yading@11: GET_SAUCE_META("encoder", 22); yading@11: yading@11: if (got_width && datatype && filetype) { yading@11: if ((datatype == 1 && filetype <=2) || (datatype == 5 && filetype == 255) || datatype == 6) { yading@11: if (t1) { yading@11: avctx->streams[0]->codec->width = t1<<3; yading@11: *got_width = 1; yading@11: } yading@11: if (get_height && t2) yading@11: avctx->streams[0]->codec->height = t2<<4; yading@11: } else if (datatype == 5) { yading@11: if (filetype) { yading@11: avctx->streams[0]->codec->width = (filetype == 1 ? t1 : filetype) << 4; yading@11: *got_width = 1; yading@11: } yading@11: if (get_height && t2) yading@11: avctx->streams[0]->codec->height = t2<<4; yading@11: } yading@11: } yading@11: yading@11: *fsize -= 128; yading@11: yading@11: if (nb_comments > 0) { yading@11: avio_seek(pb, start_pos - 64*nb_comments - 5, SEEK_SET); yading@11: if (avio_read(pb, buf, 5) == 5 && !memcmp(buf, "COMNT", 5)) { yading@11: int i; yading@11: char *str = av_malloc(65*nb_comments + 1); yading@11: *fsize -= 64*nb_comments + 5; yading@11: if (!str) yading@11: return 0; yading@11: for (i = 0; i < nb_comments; i++) { yading@11: if (avio_read(pb, str + 65*i, 64) != 64) yading@11: break; yading@11: str[65*i + 64] = '\n'; yading@11: } yading@11: str[65*i] = 0; yading@11: av_dict_set(&avctx->metadata, "comment", str, AV_DICT_DONT_STRDUP_VAL); yading@11: } yading@11: } yading@11: yading@11: return 0; yading@11: }