]> git.sesse.net Git - ffmpeg/blob - libavformat/rtpenc_h263_rfc2190.c
lavf: move CodecMime from matroska.h to internal.h
[ffmpeg] / libavformat / rtpenc_h263_rfc2190.c
1 /*
2  * RTP packetization for H.263 video
3  * Copyright (c) 2012 Martin Storsjo
4  *
5  * This file is part of Libav.
6  *
7  * Libav 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  * Libav 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 Libav; 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 "rtpenc.h"
24 #include "libavcodec/put_bits.h"
25 #include "libavcodec/get_bits.h"
26
27 struct H263Info {
28     int src;
29     int i;
30     int u;
31     int s;
32     int a;
33     int pb;
34     int tr;
35 };
36
37 static void send_mode_a(AVFormatContext *s1, const struct H263Info *info,
38                         const uint8_t *buf, int len, int m)
39 {
40     RTPMuxContext *s = s1->priv_data;
41     PutBitContext pb;
42
43     init_put_bits(&pb, s->buf, 32);
44     put_bits(&pb, 1, 0); /* F - 0, mode A */
45     put_bits(&pb, 1, 0); /* P - 0, normal I/P */
46     put_bits(&pb, 3, 0); /* SBIT - 0 bits */
47     put_bits(&pb, 3, 0); /* EBIT - 0 bits */
48     put_bits(&pb, 3, info->src); /* SRC - source format */
49     put_bits(&pb, 1, info->i); /* I - inter/intra */
50     put_bits(&pb, 1, info->u); /* U - unrestricted motion vector */
51     put_bits(&pb, 1, info->s); /* S - syntax-baesd arithmetic coding */
52     put_bits(&pb, 1, info->a); /* A - advanced prediction */
53     put_bits(&pb, 4, 0); /* R - reserved */
54     put_bits(&pb, 2, 0); /* DBQ - 0 */
55     put_bits(&pb, 3, 0); /* TRB - 0 */
56     put_bits(&pb, 8, info->tr); /* TR */
57     flush_put_bits(&pb);
58     memcpy(s->buf + 4, buf, len);
59
60     ff_rtp_send_data(s1, s->buf, len + 4, m);
61 }
62
63 void ff_rtp_send_h263_rfc2190(AVFormatContext *s1, const uint8_t *buf, int size)
64 {
65     RTPMuxContext *s = s1->priv_data;
66     int len;
67     GetBitContext gb;
68     struct H263Info info = { 0 };
69
70     s->timestamp = s->cur_timestamp;
71
72     init_get_bits(&gb, buf, size*8);
73     if (get_bits(&gb, 22) == 0x20) { /* Picture Start Code */
74         info.tr  = get_bits(&gb, 8);
75         skip_bits(&gb, 2); /* PTYPE start, H261 disambiguation */
76         skip_bits(&gb, 3); /* Split screen, document camera, freeze picture release */
77         info.src = get_bits(&gb, 3);
78         info.i   = get_bits(&gb, 1);
79         info.u   = get_bits(&gb, 1);
80         info.s   = get_bits(&gb, 1);
81         info.a   = get_bits(&gb, 1);
82         info.pb  = get_bits(&gb, 1);
83     }
84
85     while (size > 0) {
86         len = FFMIN(s->max_payload_size - 4, size);
87
88         /* Look for a better place to split the frame into packets. */
89         if (len < size) {
90             const uint8_t *end = ff_h263_find_resync_marker_reverse(buf,
91                                                                     buf + len);
92             len = end - buf;
93             if (len == s->max_payload_size - 4)
94                 av_log(s1, AV_LOG_WARNING,
95                        "No GOB boundary found within MTU size, splitting at "
96                        "a random boundary\n");
97         }
98
99         send_mode_a(s1, &info, buf, len, len == size);
100
101         buf  += len;
102         size -= len;
103     }
104 }