1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * RTP Packetization of RAW video (RFC4175) 3cabdff1aSopenharmony_ci * Copyright (c) 2021 Limin Wang 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#include "avformat.h" 22cabdff1aSopenharmony_ci#include "rtpenc.h" 23cabdff1aSopenharmony_ci 24cabdff1aSopenharmony_civoid ff_rtp_send_raw_rfc4175(AVFormatContext *s1, const uint8_t *buf, int size, int interlaced, int field) 25cabdff1aSopenharmony_ci{ 26cabdff1aSopenharmony_ci RTPMuxContext *s = s1->priv_data; 27cabdff1aSopenharmony_ci int width = s1->streams[0]->codecpar->width; 28cabdff1aSopenharmony_ci int height = s1->streams[0]->codecpar->height; 29cabdff1aSopenharmony_ci int xinc, yinc, pgroup; 30cabdff1aSopenharmony_ci int i = 0; 31cabdff1aSopenharmony_ci int offset = 0; 32cabdff1aSopenharmony_ci 33cabdff1aSopenharmony_ci s->timestamp = s->cur_timestamp; 34cabdff1aSopenharmony_ci switch (s1->streams[0]->codecpar->format) { 35cabdff1aSopenharmony_ci case AV_PIX_FMT_UYVY422: 36cabdff1aSopenharmony_ci xinc = 2; 37cabdff1aSopenharmony_ci yinc = 1 << interlaced; 38cabdff1aSopenharmony_ci pgroup = 4; 39cabdff1aSopenharmony_ci break; 40cabdff1aSopenharmony_ci case AV_PIX_FMT_YUV422P10: 41cabdff1aSopenharmony_ci xinc = 2; 42cabdff1aSopenharmony_ci yinc = 1 << interlaced; 43cabdff1aSopenharmony_ci pgroup = 5; 44cabdff1aSopenharmony_ci break; 45cabdff1aSopenharmony_ci case AV_PIX_FMT_YUV420P: 46cabdff1aSopenharmony_ci xinc = 4; 47cabdff1aSopenharmony_ci yinc = 1 << interlaced; 48cabdff1aSopenharmony_ci pgroup = 6; 49cabdff1aSopenharmony_ci break; 50cabdff1aSopenharmony_ci case AV_PIX_FMT_RGB24: 51cabdff1aSopenharmony_ci xinc = 1; 52cabdff1aSopenharmony_ci yinc = 1 << interlaced; 53cabdff1aSopenharmony_ci pgroup = 3; 54cabdff1aSopenharmony_ci break; 55cabdff1aSopenharmony_ci case AV_PIX_FMT_BGR24: 56cabdff1aSopenharmony_ci xinc = 1; 57cabdff1aSopenharmony_ci yinc = 1 << interlaced; 58cabdff1aSopenharmony_ci pgroup = 3; 59cabdff1aSopenharmony_ci break; 60cabdff1aSopenharmony_ci default: 61cabdff1aSopenharmony_ci return; 62cabdff1aSopenharmony_ci } 63cabdff1aSopenharmony_ci 64cabdff1aSopenharmony_ci while (i < height) { 65cabdff1aSopenharmony_ci int left = s->max_payload_size; 66cabdff1aSopenharmony_ci uint8_t *dest = s->buf; 67cabdff1aSopenharmony_ci uint8_t *headers; 68cabdff1aSopenharmony_ci const int head_size = 6; 69cabdff1aSopenharmony_ci int next_line; 70cabdff1aSopenharmony_ci int length, cont, pixels; 71cabdff1aSopenharmony_ci 72cabdff1aSopenharmony_ci /* Extended Sequence Number */ 73cabdff1aSopenharmony_ci *dest++ = 0; 74cabdff1aSopenharmony_ci *dest++ = 0; 75cabdff1aSopenharmony_ci left -= 2; 76cabdff1aSopenharmony_ci 77cabdff1aSopenharmony_ci headers = dest; 78cabdff1aSopenharmony_ci do { 79cabdff1aSopenharmony_ci int l_line; 80cabdff1aSopenharmony_ci 81cabdff1aSopenharmony_ci pixels = width - offset; 82cabdff1aSopenharmony_ci length = (pixels * pgroup) / xinc; 83cabdff1aSopenharmony_ci 84cabdff1aSopenharmony_ci left -= head_size; 85cabdff1aSopenharmony_ci if (left >= length) { 86cabdff1aSopenharmony_ci next_line = 1; 87cabdff1aSopenharmony_ci } else { 88cabdff1aSopenharmony_ci pixels = (left / pgroup) * xinc; 89cabdff1aSopenharmony_ci length = (pixels * pgroup) / xinc; 90cabdff1aSopenharmony_ci next_line = 0; 91cabdff1aSopenharmony_ci } 92cabdff1aSopenharmony_ci left -= length; 93cabdff1aSopenharmony_ci 94cabdff1aSopenharmony_ci /* Length */ 95cabdff1aSopenharmony_ci *dest++ = (length >> 8) & 0xff; 96cabdff1aSopenharmony_ci *dest++ = length & 0xff; 97cabdff1aSopenharmony_ci 98cabdff1aSopenharmony_ci /* Line No */ 99cabdff1aSopenharmony_ci l_line = i >> interlaced; 100cabdff1aSopenharmony_ci *dest++ = ((l_line >> 8) & 0x7f) | ((field << 7) & 0x80); 101cabdff1aSopenharmony_ci *dest++ = l_line & 0xff; 102cabdff1aSopenharmony_ci if (next_line) i += yinc; 103cabdff1aSopenharmony_ci 104cabdff1aSopenharmony_ci cont = (left > (head_size + pgroup) && i < height) ? 0x80 : 0x00; 105cabdff1aSopenharmony_ci /* Offset and Continuation marker */ 106cabdff1aSopenharmony_ci *dest++ = ((offset >> 8) & 0x7f) | cont; 107cabdff1aSopenharmony_ci *dest++ = offset & 0xff; 108cabdff1aSopenharmony_ci 109cabdff1aSopenharmony_ci if (next_line) 110cabdff1aSopenharmony_ci offset = 0; 111cabdff1aSopenharmony_ci else 112cabdff1aSopenharmony_ci offset += pixels; 113cabdff1aSopenharmony_ci } while (cont); 114cabdff1aSopenharmony_ci 115cabdff1aSopenharmony_ci do { 116cabdff1aSopenharmony_ci int l_field; 117cabdff1aSopenharmony_ci int l_line; 118cabdff1aSopenharmony_ci int l_off; 119cabdff1aSopenharmony_ci int copy_offset; 120cabdff1aSopenharmony_ci 121cabdff1aSopenharmony_ci length = (headers[0] << 8) | headers[1]; 122cabdff1aSopenharmony_ci l_field = (headers[2] & 0x80) >> 7; 123cabdff1aSopenharmony_ci l_line = ((headers[2] & 0x7f) << 8) | headers[3]; 124cabdff1aSopenharmony_ci l_off = ((headers[4] & 0x7f) << 8) | headers[5]; 125cabdff1aSopenharmony_ci cont = headers[4] & 0x80; 126cabdff1aSopenharmony_ci headers += head_size; 127cabdff1aSopenharmony_ci 128cabdff1aSopenharmony_ci if (interlaced) 129cabdff1aSopenharmony_ci l_line = 2 * l_line + l_field; 130cabdff1aSopenharmony_ci copy_offset = (l_line * width + l_off) * pgroup / xinc; 131cabdff1aSopenharmony_ci if (copy_offset + length > size) 132cabdff1aSopenharmony_ci break; 133cabdff1aSopenharmony_ci memcpy (dest, buf + copy_offset, length); 134cabdff1aSopenharmony_ci dest += length; 135cabdff1aSopenharmony_ci } while (cont); 136cabdff1aSopenharmony_ci 137cabdff1aSopenharmony_ci ff_rtp_send_data (s1, s->buf, s->max_payload_size - left, i >= height); 138cabdff1aSopenharmony_ci } 139cabdff1aSopenharmony_ci} 140