Statistics
| Branch: | Revision:

streamers / out-stream-avf.c @ 9cc07b6c

History | View | Annotate | Download (3.07 KB)

1
/*
2
 *  Copyright (c) 2010 Luca Abeni
3
 *
4
 *  This is free software; see gpl-3.0.txt
5
 */
6

    
7
#include <libavformat/avformat.h>
8
#include <stdio.h>
9

    
10
#include "out-stream.h"
11
#include "dbg.h"
12

    
13
static const char *output_format = "nut";
14
static const char *output_file = "out.nut";
15

    
16
static enum CodecID libav_codec_id(uint8_t mytype)
17
{
18
  switch (mytype) {
19
    case 1:
20
      return CODEC_ID_MPEG2VIDEO;
21
    case 2:
22
      return CODEC_ID_H261;
23
    case 3:
24
      return CODEC_ID_H263P;
25
    case 4:
26
      return CODEC_ID_MJPEG;
27
    case 5:
28
      return CODEC_ID_MPEG4;
29
    case 6:
30
      return CODEC_ID_FLV1;
31
    case 7:
32
      return CODEC_ID_SVQ3;
33
    case 8:
34
      return CODEC_ID_DVVIDEO;
35
    case 9:
36
      return CODEC_ID_H264;
37
    case 10:
38
      return CODEC_ID_THEORA;
39
    case 11:
40
      return CODEC_ID_SNOW;
41
    case 12:
42
      return CODEC_ID_VP6;
43
    case 13:
44
      return CODEC_ID_DIRAC;
45
    default:
46
      fprintf(stderr, "Unknown codec %d\n", mytype);
47
      return 0;
48
  }
49
}
50

    
51
static AVFormatContext *format_init(const uint8_t *data)
52
{
53
  AVFormatContext *of;
54
  AVCodecContext *c;
55
  AVOutputFormat *outfmt;
56
  int width, height, frame_rate_n, frame_rate_d;
57

    
58
  av_register_all();
59

    
60
  width = data[1] << 8 | data[2];
61
  height = data[3] << 8 | data[4];
62
  frame_rate_n = data[5] << 8 | data[6];
63
  frame_rate_d = data[7] << 8 | data[8];
64
  dprintf("Frame size: %dx%d -- Frame rate: %d / %d\n", width, height, frame_rate_n, frame_rate_d);
65

    
66
  outfmt = av_guess_format(output_format, NULL, NULL);
67
  of = avformat_alloc_context();
68
  if (of == NULL) {
69
    return NULL;
70
  }
71
  of->oformat = outfmt;
72
  av_new_stream(of, 0);
73
  c = of->streams[0]->codec;
74
  c->codec_id = libav_codec_id(data[0]);
75
  c->codec_type = CODEC_TYPE_VIDEO;
76
  c->width = width;
77
  c->height= height;
78
  c->time_base.den = frame_rate_n;
79
  c->time_base.num = frame_rate_d;
80
  of->streams[0]->avg_frame_rate.num = frame_rate_n;
81
  of->streams[0]->avg_frame_rate.den = frame_rate_d;
82
  c->pix_fmt = PIX_FMT_YUV420P;
83

    
84
  return of;
85
}
86

    
87
void chunk_write(int id, const uint8_t *data, int size)
88
{
89
  static AVFormatContext *outctx;
90
  const int header_size = 1 + 2 + 2 + 2 + 2 + 1; // 1 Frame type + 2 width + 2 height + 2 frame rate num + 2 frame rate den + 1 number of frames
91
  int frames, i;
92

    
93
  if (data[0] > 127) {
94
    fprintf(stderr, "Error! Non video chunk: %x!!!\n", data[0]);
95
    return;
96
  }
97
  if (outctx == NULL) {
98
    outctx = format_init(data);
99
    if (outctx == NULL) {
100
      fprintf(stderr, "Format init failed\n");
101

    
102
      return;
103
    }
104
    av_set_parameters(outctx, NULL);
105
    snprintf(outctx->filename, sizeof(outctx->filename), "%s", output_file);
106
    dump_format(outctx, 0, output_file, 1);
107
    url_fopen(&outctx->pb, output_file, URL_WRONLY);
108
    av_write_header(outctx);
109
  }
110

    
111
  frames = data[9];
112
  for (i = 0; i < frames; i++) {
113
    AVPacket pkt;
114

    
115
    dprintf("Frame %d has size %d\n", i, data[10 + 2 * i] << 8 | data[11 + 2 * i]);
116
    av_init_packet(&pkt);
117
    pkt.stream_index = 0;        // FIXME!
118
    pkt.pts = AV_NOPTS_VALUE;        // FIXME!
119
    pkt.data = data + header_size + frames * 2;
120
    pkt.size = data[10 + 2 * i] << 8 | data[11 + 2 * i];
121
    av_interleaved_write_frame(outctx, &pkt);
122
  }
123
}