xref: /third_party/ffmpeg/libavformat/sauce.c (revision cabdff1a)
1cabdff1aSopenharmony_ci/*
2cabdff1aSopenharmony_ci * SAUCE header parser
3cabdff1aSopenharmony_ci * Copyright (c) 2010 Peter Ross <pross@xvid.org>
4cabdff1aSopenharmony_ci *
5cabdff1aSopenharmony_ci * This file is part of FFmpeg.
6cabdff1aSopenharmony_ci *
7cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or
8cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public
9cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either
10cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version.
11cabdff1aSopenharmony_ci *
12cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful,
13cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
14cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15cabdff1aSopenharmony_ci * Lesser General Public License for more details.
16cabdff1aSopenharmony_ci *
17cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public
18cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software
19cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20cabdff1aSopenharmony_ci */
21cabdff1aSopenharmony_ci
22cabdff1aSopenharmony_ci/**
23cabdff1aSopenharmony_ci * @file
24cabdff1aSopenharmony_ci * SAUCE header parser
25cabdff1aSopenharmony_ci */
26cabdff1aSopenharmony_ci
27cabdff1aSopenharmony_ci#include "libavutil/intreadwrite.h"
28cabdff1aSopenharmony_ci#include "libavutil/dict.h"
29cabdff1aSopenharmony_ci#include "avformat.h"
30cabdff1aSopenharmony_ci#include "sauce.h"
31cabdff1aSopenharmony_ci
32cabdff1aSopenharmony_ciint ff_sauce_read(AVFormatContext *avctx, uint64_t *fsize, int *got_width, int get_height)
33cabdff1aSopenharmony_ci{
34cabdff1aSopenharmony_ci    AVIOContext *pb = avctx->pb;
35cabdff1aSopenharmony_ci    char buf[36];
36cabdff1aSopenharmony_ci    int datatype, filetype, t1, t2, nb_comments;
37cabdff1aSopenharmony_ci    uint64_t start_pos = avio_size(pb) - 128;
38cabdff1aSopenharmony_ci
39cabdff1aSopenharmony_ci    avio_seek(pb, start_pos, SEEK_SET);
40cabdff1aSopenharmony_ci    if (avio_read(pb, buf, 7) != 7)
41cabdff1aSopenharmony_ci        return -1;
42cabdff1aSopenharmony_ci    if (memcmp(buf, "SAUCE00", 7))
43cabdff1aSopenharmony_ci        return -1;
44cabdff1aSopenharmony_ci
45cabdff1aSopenharmony_ci#define GET_SAUCE_META(name,size) \
46cabdff1aSopenharmony_ci    if (avio_read(pb, buf, size) == size && buf[0]) { \
47cabdff1aSopenharmony_ci        buf[size] = 0; \
48cabdff1aSopenharmony_ci        av_dict_set(&avctx->metadata, name, buf, 0); \
49cabdff1aSopenharmony_ci    }
50cabdff1aSopenharmony_ci
51cabdff1aSopenharmony_ci    GET_SAUCE_META("title",     35)
52cabdff1aSopenharmony_ci    GET_SAUCE_META("artist",    20)
53cabdff1aSopenharmony_ci    GET_SAUCE_META("publisher", 20)
54cabdff1aSopenharmony_ci    GET_SAUCE_META("date",      8)
55cabdff1aSopenharmony_ci    avio_skip(pb, 4);
56cabdff1aSopenharmony_ci    datatype    = avio_r8(pb);
57cabdff1aSopenharmony_ci    filetype    = avio_r8(pb);
58cabdff1aSopenharmony_ci    t1          = avio_rl16(pb);
59cabdff1aSopenharmony_ci    t2          = avio_rl16(pb);
60cabdff1aSopenharmony_ci    nb_comments = avio_r8(pb);
61cabdff1aSopenharmony_ci    avio_skip(pb, 1); /* flags */
62cabdff1aSopenharmony_ci    avio_skip(pb, 4);
63cabdff1aSopenharmony_ci    GET_SAUCE_META("encoder",   22);
64cabdff1aSopenharmony_ci
65cabdff1aSopenharmony_ci    if (got_width && datatype && filetype) {
66cabdff1aSopenharmony_ci        if ((datatype == 1 && filetype <=2) || (datatype == 5 && filetype == 255) || datatype == 6) {
67cabdff1aSopenharmony_ci            if (t1) {
68cabdff1aSopenharmony_ci                avctx->streams[0]->codecpar->width = t1<<3;
69cabdff1aSopenharmony_ci                *got_width = 1;
70cabdff1aSopenharmony_ci            }
71cabdff1aSopenharmony_ci            if (get_height && t2)
72cabdff1aSopenharmony_ci                avctx->streams[0]->codecpar->height = t2<<4;
73cabdff1aSopenharmony_ci        } else if (datatype == 5) {
74cabdff1aSopenharmony_ci            if (filetype) {
75cabdff1aSopenharmony_ci                avctx->streams[0]->codecpar->width = (filetype == 1 ? t1 : filetype) << 4;
76cabdff1aSopenharmony_ci                *got_width = 1;
77cabdff1aSopenharmony_ci            }
78cabdff1aSopenharmony_ci            if (get_height && t2)
79cabdff1aSopenharmony_ci                avctx->streams[0]->codecpar->height = t2<<4;
80cabdff1aSopenharmony_ci        }
81cabdff1aSopenharmony_ci    }
82cabdff1aSopenharmony_ci
83cabdff1aSopenharmony_ci    *fsize -= 128;
84cabdff1aSopenharmony_ci
85cabdff1aSopenharmony_ci    if (nb_comments > 0) {
86cabdff1aSopenharmony_ci        avio_seek(pb, start_pos - 64*nb_comments - 5, SEEK_SET);
87cabdff1aSopenharmony_ci        if (avio_read(pb, buf, 5) == 5 && !memcmp(buf, "COMNT", 5)) {
88cabdff1aSopenharmony_ci            int i;
89cabdff1aSopenharmony_ci            char *str = av_malloc(65*nb_comments + 1);
90cabdff1aSopenharmony_ci            *fsize -= 64*nb_comments + 5;
91cabdff1aSopenharmony_ci            if (!str)
92cabdff1aSopenharmony_ci                return 0;
93cabdff1aSopenharmony_ci            for (i = 0; i < nb_comments; i++) {
94cabdff1aSopenharmony_ci                if (avio_read(pb, str + 65*i, 64) != 64)
95cabdff1aSopenharmony_ci                    break;
96cabdff1aSopenharmony_ci                str[65*i + 64] = '\n';
97cabdff1aSopenharmony_ci            }
98cabdff1aSopenharmony_ci            str[65*i] = 0;
99cabdff1aSopenharmony_ci            av_dict_set(&avctx->metadata, "comment", str, AV_DICT_DONT_STRDUP_VAL);
100cabdff1aSopenharmony_ci        }
101cabdff1aSopenharmony_ci    }
102cabdff1aSopenharmony_ci
103cabdff1aSopenharmony_ci    return 0;
104cabdff1aSopenharmony_ci}
105