blob: 996412adb99af23c9c0297ef04b0d0ddeff478d2
1 | /* |
2 | * Raw video utils |
3 | * Copyright (c) 2016 Michael Niedermayer |
4 | * |
5 | * This file is part of FFmpeg. |
6 | * |
7 | * FFmpeg is free software; you can redistribute it and/or |
8 | * modify it under the terms of the GNU Lesser General Public |
9 | * License as published by the Free Software Foundation; either |
10 | * version 2.1 of the License, or (at your option) any later version. |
11 | * |
12 | * FFmpeg is distributed in the hope that it will be useful, |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
15 | * Lesser General Public License for more details. |
16 | * |
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 |
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
20 | */ |
21 | |
22 | #include "avformat.h" |
23 | #include "internal.h" |
24 | |
25 | int ff_reshuffle_raw_rgb(AVFormatContext *s, AVPacket **ppkt, AVCodecParameters *par, int expected_stride) |
26 | { |
27 | int ret; |
28 | AVPacket *pkt = *ppkt; |
29 | int64_t bpc = par->bits_per_coded_sample != 15 ? par->bits_per_coded_sample : 16; |
30 | int min_stride = (par->width * bpc + 7) >> 3; |
31 | int with_pal_size = min_stride * par->height + 1024; |
32 | int contains_pal = bpc == 8 && pkt->size == with_pal_size; |
33 | int size = contains_pal ? min_stride * par->height : pkt->size; |
34 | int stride = size / par->height; |
35 | int padding = expected_stride - FFMIN(expected_stride, stride); |
36 | int y; |
37 | AVPacket *new_pkt; |
38 | |
39 | if (pkt->size == expected_stride * par->height) |
40 | return 0; |
41 | if (size != stride * par->height) |
42 | return 0; |
43 | |
44 | new_pkt = av_packet_alloc(); |
45 | if (!new_pkt) |
46 | return AVERROR(ENOMEM); |
47 | |
48 | ret = av_new_packet(new_pkt, expected_stride * par->height); |
49 | if (ret < 0) |
50 | goto fail; |
51 | |
52 | ret = av_packet_copy_props(new_pkt, pkt); |
53 | if (ret < 0) |
54 | goto fail; |
55 | |
56 | for (y = 0; y<par->height; y++) { |
57 | memcpy(new_pkt->data + y*expected_stride, pkt->data + y*stride, FFMIN(expected_stride, stride)); |
58 | memset(new_pkt->data + y*expected_stride + expected_stride - padding, 0, padding); |
59 | } |
60 | |
61 | *ppkt = new_pkt; |
62 | return 1 + contains_pal; |
63 | fail: |
64 | av_packet_free(&new_pkt); |
65 | |
66 | return ret; |
67 | } |
68 |