You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

302 lines
8.5KB

  1. /*
  2. * Output a MPEG1 multiplexed video/audio stream
  3. * Copyright (c) 2000 Gerard Lantau.
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. */
  19. #include <stdlib.h>
  20. #include <stdio.h>
  21. #include <netinet/in.h>
  22. #include <linux/videodev.h>
  23. #include <unistd.h>
  24. #include <fcntl.h>
  25. #include <sys/ioctl.h>
  26. #include <sys/mman.h>
  27. #include <errno.h>
  28. #include <sys/time.h>
  29. #include <getopt.h>
  30. #include "mpegenc.h"
  31. #include "mpegvideo.h"
  32. #include "mpegaudio.h"
  33. #define MAX_PAYLOAD_SIZE 4096
  34. #define NB_STREAMS 2
  35. typedef struct {
  36. UINT8 buffer[MAX_PAYLOAD_SIZE];
  37. int buffer_ptr;
  38. UINT8 id;
  39. int max_buffer_size;
  40. int packet_number;
  41. AVEncodeContext *enc;
  42. float pts;
  43. } StreamInfo;
  44. typedef struct {
  45. int packet_size; /* required packet size */
  46. int packet_number;
  47. int pack_header_freq; /* frequency (in packets^-1) at which we send pack headers */
  48. int system_header_freq;
  49. int mux_rate; /* bitrate in units of 50 bytes/s */
  50. /* stream info */
  51. int nb_streams;
  52. StreamInfo streams[NB_STREAMS];
  53. AVFormatContext *ctx;
  54. } MpegMuxContext;
  55. #define PACK_START_CODE ((unsigned int)0x000001ba)
  56. #define SYSTEM_HEADER_START_CODE ((unsigned int)0x000001bb)
  57. #define PACKET_START_CODE_MASK ((unsigned int)0xffffff00)
  58. #define PACKET_START_CODE_PREFIX ((unsigned int)0x00000100)
  59. #define ISO_11172_END_CODE ((unsigned int)0x000001b9)
  60. #define AUDIO_ID 0xc0
  61. #define VIDEO_ID 0xe0
  62. static int put_pack_header(MpegMuxContext *s, UINT8 *buf, long long timestamp)
  63. {
  64. PutBitContext pb;
  65. init_put_bits(&pb, buf, 128, NULL, NULL);
  66. put_bits(&pb, 32, PACK_START_CODE);
  67. put_bits(&pb, 4, 0x2);
  68. put_bits(&pb, 3, (timestamp >> 30) & 0x07);
  69. put_bits(&pb, 1, 1);
  70. put_bits(&pb, 15, (timestamp >> 15) & 0x7fff);
  71. put_bits(&pb, 1, 1);
  72. put_bits(&pb, 15, (timestamp) & 0x7fff);
  73. put_bits(&pb, 1, 1);
  74. put_bits(&pb, 1, 1);
  75. put_bits(&pb, 22, s->mux_rate);
  76. flush_put_bits(&pb);
  77. return pb.buf_ptr - pb.buf;
  78. }
  79. static int put_system_header(MpegMuxContext *s, UINT8 *buf)
  80. {
  81. int audio_bound, video_bound;
  82. int size, rate_bound, i;
  83. PutBitContext pb;
  84. init_put_bits(&pb, buf, 128, NULL, NULL);
  85. put_bits(&pb, 32, SYSTEM_HEADER_START_CODE);
  86. put_bits(&pb, 16, 0);
  87. put_bits(&pb, 1, 1);
  88. rate_bound = s->mux_rate; /* maximum bit rate of the multiplexed stream */
  89. put_bits(&pb, 22, rate_bound);
  90. put_bits(&pb, 1, 1); /* marker */
  91. audio_bound = 1; /* at most one audio stream */
  92. put_bits(&pb, 6, audio_bound);
  93. put_bits(&pb, 1, 0); /* variable bitrate */
  94. put_bits(&pb, 1, 0); /* non constrainted bit stream */
  95. put_bits(&pb, 1, 1); /* audio locked */
  96. put_bits(&pb, 1, 1); /* video locked */
  97. put_bits(&pb, 1, 1); /* marker */
  98. video_bound = 1; /* at most one video stream */
  99. put_bits(&pb, 5, video_bound);
  100. put_bits(&pb, 8, 0xff); /* reserved byte */
  101. /* audio stream info */
  102. for(i=0;i<s->nb_streams;i++) {
  103. put_bits(&pb, 8, s->streams[i].id); /* stream ID */
  104. put_bits(&pb, 2, 3);
  105. put_bits(&pb, 1, 1); /* buffer bound scale = 1024 */
  106. put_bits(&pb, 13, s->streams[i].max_buffer_size); /* max buffer size */
  107. }
  108. /* no more streams */
  109. put_bits(&pb, 1, 0);
  110. flush_put_bits(&pb);
  111. size = pb.buf_ptr - pb.buf;
  112. /* patch packet size */
  113. buf[4] = (size - 6) >> 8;
  114. buf[5] = (size - 6) & 0xff;
  115. return size;
  116. }
  117. /* Format a packet header for a total size of 'total_size'. Return the
  118. header size */
  119. static int put_packet_header(MpegMuxContext *s,
  120. int id, long long timestamp,
  121. UINT8 *buffer, int total_size)
  122. {
  123. UINT8 *buf_ptr;
  124. PutBitContext pb;
  125. int size, payload_size;
  126. #if 0
  127. printf("packet ID=%2x PTS=%0.3f size=%d\n",
  128. id, timestamp / 90000.0, total_size);
  129. #endif
  130. buf_ptr = buffer;
  131. if ((s->packet_number % s->pack_header_freq) == 0) {
  132. /* output pack and systems header */
  133. size = put_pack_header(s, buf_ptr, timestamp);
  134. buf_ptr += size;
  135. if ((s->packet_number % s->system_header_freq) == 0) {
  136. size = put_system_header(s, buf_ptr);
  137. buf_ptr += size;
  138. }
  139. }
  140. payload_size = total_size - ((buf_ptr - buffer) + 6 + 5);
  141. /* packet header */
  142. init_put_bits(&pb, buf_ptr, 128, NULL, NULL);
  143. put_bits(&pb, 32, PACKET_START_CODE_PREFIX + id);
  144. put_bits(&pb, 16, payload_size + 5);
  145. /* presentation time stamp */
  146. put_bits(&pb, 4, 0x02);
  147. put_bits(&pb, 3, (timestamp >> 30) & 0x07);
  148. put_bits(&pb, 1, 1);
  149. put_bits(&pb, 15, (timestamp >> 15) & 0x7fff);
  150. put_bits(&pb, 1, 1);
  151. put_bits(&pb, 15, (timestamp) & 0x7fff);
  152. put_bits(&pb, 1, 1);
  153. flush_put_bits(&pb);
  154. s->packet_number++;
  155. return pb.buf_ptr - buffer;
  156. }
  157. int mpeg_mux_init(AVFormatContext *ctx)
  158. {
  159. MpegMuxContext *s;
  160. int bitrate, i;
  161. s = malloc(sizeof(MpegMuxContext));
  162. if (!s)
  163. return -1;
  164. memset(s, 0, sizeof(MpegMuxContext));
  165. ctx->priv_data = s;
  166. s->ctx = ctx;
  167. s->packet_number = 0;
  168. /* XXX: hardcoded */
  169. s->packet_size = 2048;
  170. s->nb_streams = 2;
  171. s->streams[0].id = AUDIO_ID;
  172. s->streams[0].max_buffer_size = 10; /* in KBytes */
  173. s->streams[0].enc = ctx->audio_enc;
  174. s->streams[1].id = VIDEO_ID;
  175. s->streams[1].max_buffer_size = 50; /* in KBytes */
  176. s->streams[1].enc = ctx->video_enc;
  177. /* we increase slightly the bitrate to take into account the
  178. headers. XXX: compute it exactly */
  179. bitrate = 2000;
  180. for(i=0;i<s->nb_streams;i++) {
  181. bitrate += s->streams[i].enc->bit_rate;
  182. }
  183. s->mux_rate = (bitrate + (8 * 50) - 1) / (8 * 50);
  184. /* every 2 seconds */
  185. s->pack_header_freq = 2 * bitrate / s->packet_size / 8;
  186. /* every 10 seconds */
  187. s->system_header_freq = s->pack_header_freq * 5;
  188. for(i=0;i<NB_STREAMS;i++) {
  189. s->streams[i].buffer_ptr = 0;
  190. s->streams[i].packet_number = 0;
  191. s->streams[i].pts = 0;
  192. }
  193. return 0;
  194. }
  195. int mpeg_mux_end(AVFormatContext *ctx)
  196. {
  197. PutBitContext pb;
  198. UINT8 buffer[128];
  199. /* write the end header */
  200. init_put_bits(&pb, buffer, sizeof(buffer), NULL, NULL);
  201. put_bits(&pb, 32, ISO_11172_END_CODE);
  202. put_buffer(&ctx->pb, buffer, pb.buf_ptr - buffer);
  203. put_flush_packet(&ctx->pb);
  204. return 0;
  205. }
  206. static void write_stream(MpegMuxContext *s, StreamInfo *stream, UINT8 *buf, int size)
  207. {
  208. int len, len1, header_size;
  209. long long pts;
  210. while (size > 0) {
  211. if (stream->buffer_ptr == 0) {
  212. pts = stream->pts * 90000.0;
  213. header_size = put_packet_header(s, stream->id, pts, stream->buffer, s->packet_size);
  214. stream->buffer_ptr = header_size;
  215. }
  216. len = size;
  217. len1 = s->packet_size - stream->buffer_ptr;
  218. if (len > len1)
  219. len = len1;
  220. memcpy(stream->buffer + stream->buffer_ptr, buf, len);
  221. stream->buffer_ptr += len;
  222. if (stream->buffer_ptr == s->packet_size) {
  223. /* output the packet */
  224. put_buffer(&s->ctx->pb, stream->buffer, s->packet_size);
  225. put_flush_packet(&s->ctx->pb);
  226. stream->buffer_ptr = 0;
  227. stream->packet_number++;
  228. }
  229. buf += len;
  230. size -= len;
  231. }
  232. }
  233. static int mpeg_mux_write_audio(AVFormatContext *ctx, UINT8 *buf, int size)
  234. {
  235. MpegMuxContext *s = ctx->priv_data;
  236. write_stream(s, &s->streams[0], buf, size);
  237. s->streams[0].pts += (float)s->streams[0].enc->frame_size / s->streams[0].enc->rate;
  238. return 0;
  239. }
  240. int mpeg_mux_write_video(AVFormatContext *ctx, UINT8 *buf, int size)
  241. {
  242. MpegMuxContext *s = ctx->priv_data;
  243. write_stream(s, &s->streams[1], buf, size);
  244. s->streams[1].pts += 1.0 / (float)s->streams[1].enc->rate;
  245. return 0;
  246. }
  247. AVFormat mpeg_mux_format = {
  248. "mpeg1",
  249. "MPEG1 multiplex format",
  250. "video/mpeg",
  251. "mpg,mpeg",
  252. CODEC_ID_MP2,
  253. CODEC_ID_MPEG1VIDEO,
  254. mpeg_mux_init,
  255. mpeg_mux_write_audio,
  256. mpeg_mux_write_video,
  257. mpeg_mux_end,
  258. };