Mercurial > mplayer.hg
comparison libmpdemux/demux_rawdv.c @ 6925:cc46462d0015
raw .dv stream demuxer by Alexander Neundorf <neundorf@kde.org>
author | arpi |
---|---|
date | Mon, 05 Aug 2002 17:21:35 +0000 |
parents | |
children | a715a0960762 |
comparison
equal
deleted
inserted
replaced
6924:765d3da45d57 | 6925:cc46462d0015 |
---|---|
1 /* | |
2 raw dv file parser for MPlayer | |
3 by Alexander Neundorf <neundorf@kde.org> | |
4 based on the fli demuxer | |
5 | |
6 LGPL | |
7 */ | |
8 | |
9 #include <stdio.h> | |
10 #include <stdlib.h> | |
11 #include <unistd.h> | |
12 | |
13 #include "config.h" | |
14 | |
15 #ifdef HAVE_LIBDV095 | |
16 | |
17 #include "mp_msg.h" | |
18 #include "help_mp.h" | |
19 | |
20 #include "stream.h" | |
21 #include "demuxer.h" | |
22 #include "stheader.h" | |
23 | |
24 #include <libdv/dv.h> | |
25 #include <libdv/dv_types.h> | |
26 | |
27 #define DV_PAL_FRAME_SIZE 144000 | |
28 #define DV_NTSC_FRAME_SIZE 122000 | |
29 | |
30 typedef struct | |
31 { | |
32 int current_frame; | |
33 int frame_size; | |
34 int current_filepos; | |
35 int frame_number; | |
36 dv_decoder_t *decoder; | |
37 } rawdv_frames_t; | |
38 | |
39 void demux_seek_rawdv(demuxer_t *demuxer,float rel_seek_secs,int flags) | |
40 { | |
41 rawdv_frames_t *frames = (rawdv_frames_t *)demuxer->priv; | |
42 sh_video_t *sh_video = demuxer->video->sh; | |
43 int newpos=(flags&1)?0:frames->current_frame; | |
44 if(flags&2) | |
45 { | |
46 // float 0..1 | |
47 newpos+=rel_seek_secs*frames->frame_number; | |
48 } | |
49 else | |
50 { | |
51 // secs | |
52 newpos+=rel_seek_secs*sh_video->fps; | |
53 } | |
54 if(newpos<0) | |
55 newpos=0; | |
56 else if(newpos>frames->frame_number) | |
57 newpos=frames->frame_number; | |
58 frames->current_frame=newpos; | |
59 frames->current_filepos=newpos*frames->frame_size; | |
60 } | |
61 | |
62 int check_file_rawdv(demuxer_t *demuxer) | |
63 { | |
64 unsigned char tmp_buffer[DV_PAL_FRAME_SIZE]; | |
65 int bytes_read=0; | |
66 int result=0; | |
67 dv_decoder_t *td; | |
68 stream_reset(demuxer->stream); | |
69 stream_seek(demuxer->stream, 0); | |
70 bytes_read=stream_read(demuxer->stream,tmp_buffer,DV_PAL_FRAME_SIZE); | |
71 if ((bytes_read!=DV_PAL_FRAME_SIZE) && (bytes_read!=DV_NTSC_FRAME_SIZE)) | |
72 return 0; | |
73 | |
74 td=dv_decoder_new(TRUE,TRUE,FALSE); | |
75 td->quality=DV_QUALITY_BEST; | |
76 dv_parse_header(td, tmp_buffer); | |
77 if ((( td->num_dif_seqs==10) || (td->num_dif_seqs==12)) | |
78 && (td->width==720) | |
79 && ((td->height==576) || (td->height==480))) | |
80 result=1; | |
81 dv_decoder_free(td); | |
82 return result; | |
83 } | |
84 | |
85 // return value: | |
86 // 0 = EOF or no stream found | |
87 // 1 = successfully read a packet | |
88 int demux_rawdv_fill_buffer(demuxer_t *demuxer) | |
89 { | |
90 rawdv_frames_t *frames = (rawdv_frames_t *)demuxer->priv; | |
91 demux_packet_t* dp_video=NULL; | |
92 sh_video_t *sh_video = demuxer->video->sh; | |
93 int bytes_read=0; | |
94 // fprintf(stderr,"demux_rawdv_fill_buffer() seek to %d, size: %d\n",frames->current_filepos,frames->frame_size); | |
95 // fetch the frame from the file | |
96 // first, position the file properly since ds_read_packet() doesn't | |
97 // seem to do it, even though it takes a file offset as a parameter | |
98 stream_seek(demuxer->stream, frames->current_filepos); | |
99 | |
100 dp_video=new_demux_packet(frames->frame_size); | |
101 bytes_read=stream_read(demuxer->stream,dp_video->buffer,frames->frame_size); | |
102 if (bytes_read<frames->frame_size) | |
103 return 0; | |
104 dp_video->pts=frames->current_frame/sh_video->fps; | |
105 dp_video->pos=frames->current_filepos; | |
106 dp_video->flags=0; | |
107 | |
108 if (demuxer->audio) | |
109 { | |
110 demux_packet_t* dp_audio=clone_demux_packet(dp_video); | |
111 ds_add_packet(demuxer->audio,dp_audio); | |
112 } | |
113 ds_add_packet(demuxer->video,dp_video); | |
114 // get the next frame ready | |
115 frames->current_filepos+=frames->frame_size; | |
116 frames->current_frame++; | |
117 // fprintf(stderr," audio->packs: %d , video->packs: %d \n",demuxer->audio->packs, demuxer->video->packs); | |
118 return 1; | |
119 } | |
120 | |
121 demuxer_t* demux_open_rawdv(demuxer_t* demuxer) | |
122 { | |
123 unsigned char dv_frame[DV_PAL_FRAME_SIZE]; | |
124 sh_video_t *sh_video = NULL; | |
125 rawdv_frames_t *frames = (rawdv_frames_t *)malloc(sizeof(rawdv_frames_t)); | |
126 dv_decoder_t *dv_decoder=NULL; | |
127 | |
128 mp_msg(MSGT_DEMUXER,MSGL_V,"demux_open_rawdv() end_pos %d\n",demuxer->stream->end_pos); | |
129 | |
130 // go back to the beginning | |
131 stream_reset(demuxer->stream); | |
132 stream_seek(demuxer->stream, 0); | |
133 | |
134 //get the first frame | |
135 stream_read(demuxer->stream, dv_frame, DV_PAL_FRAME_SIZE); | |
136 | |
137 //read params from this frame | |
138 dv_decoder=dv_decoder_new(TRUE,TRUE,FALSE); | |
139 dv_decoder->quality=DV_QUALITY_BEST; | |
140 | |
141 dv_parse_header(dv_decoder, dv_frame); | |
142 | |
143 // create a new video stream header | |
144 sh_video = new_sh_video(demuxer, 0); | |
145 | |
146 // make sure the demuxer knows about the new video stream header | |
147 // (even though new_sh_video() ought to take care of it) | |
148 demuxer->seekable = 1; | |
149 demuxer->video->sh = sh_video; | |
150 | |
151 // make sure that the video demuxer stream header knows about its | |
152 // parent video demuxer stream (this is getting wacky), or else | |
153 // video_read_properties() will choke | |
154 sh_video->ds = demuxer->video; | |
155 | |
156 // custom fourcc for internal MPlayer use | |
157 // sh_video->format = mmioFOURCC('R', 'A', 'D', 'V'); | |
158 sh_video->format = mmioFOURCC('D', 'V', 'S', 'D'); | |
159 | |
160 sh_video->disp_w = dv_decoder->width; | |
161 sh_video->disp_h = dv_decoder->height; | |
162 mp_msg(MSGT_DEMUXER,MSGL_V,"demux_open_rawdv() frame_size: %d w: %d h: %d dif_seq: %d system: %d\n",dv_decoder->frame_size,dv_decoder->width, dv_decoder->height,dv_decoder->num_dif_seqs,dv_decoder->system); | |
163 | |
164 sh_video->fps= (dv_decoder->system==e_dv_system_525_60?29.97:25); | |
165 sh_video->frametime = 1.0/sh_video->fps; | |
166 | |
167 // emulate BITMAPINFOHEADER for win32 decoders: | |
168 sh_video->bih=malloc(sizeof(BITMAPINFOHEADER)); | |
169 memset(sh_video->bih,0,sizeof(BITMAPINFOHEADER)); | |
170 sh_video->bih->biSize=40; | |
171 sh_video->bih->biWidth = dv_decoder->width; | |
172 sh_video->bih->biHeight = dv_decoder->height; | |
173 sh_video->bih->biPlanes=1; | |
174 sh_video->bih->biBitCount=24; | |
175 sh_video->bih->biCompression=sh_video->format; // "DVSD" | |
176 sh_video->bih->biSizeImage=sh_video->bih->biWidth*sh_video->bih->biHeight*3; | |
177 | |
178 | |
179 frames->current_filepos=0; | |
180 frames->current_frame=0; | |
181 frames->frame_size=dv_decoder->frame_size; | |
182 frames->frame_number=demuxer->stream->end_pos/frames->frame_size; | |
183 | |
184 mp_msg(MSGT_DEMUXER,MSGL_V,"demux_open_rawdv() seek to %d, size: %d, dv_dec->frame_size: %d\n",frames->current_filepos,frames->frame_size, dv_decoder->frame_size); | |
185 if (dv_decoder->audio != NULL){ | |
186 sh_audio_t *sh_audio = new_sh_audio(demuxer, 0); | |
187 demuxer->audio->sh = sh_audio; | |
188 sh_audio->ds = demuxer->audio; | |
189 mp_msg(MSGT_DEMUXER,MSGL_V,"demux_open_rawdv() chan: %d samplerate: %d\n",dv_decoder->audio->num_channels,dv_decoder->audio->frequency ); | |
190 // custom fourcc for internal MPlayer use | |
191 sh_audio->format = mmioFOURCC('R', 'A', 'D', 'V'); | |
192 | |
193 sh_audio->wf = malloc(sizeof(WAVEFORMATEX)); | |
194 memset(sh_audio->wf, 0, sizeof(WAVEFORMATEX)); | |
195 sh_audio->wf->wFormatTag = sh_audio->format; | |
196 sh_audio->wf->nChannels = dv_decoder->audio->num_channels; | |
197 sh_audio->wf->wBitsPerSample = 16; | |
198 sh_audio->wf->nSamplesPerSec = dv_decoder->audio->frequency; | |
199 // info about the input stream: | |
200 sh_audio->wf->nAvgBytesPerSec = sh_video->fps*dv_decoder->frame_size; | |
201 sh_audio->wf->nBlockAlign = dv_decoder->frame_size; | |
202 | |
203 // sh_audio->context=(void*)dv_decoder; | |
204 } | |
205 stream_reset(demuxer->stream); | |
206 stream_seek(demuxer->stream, 0); | |
207 dv_decoder_free(dv_decoder); //we keep this in the context of both stream headers | |
208 demuxer->priv=frames; | |
209 return demuxer; | |
210 } | |
211 | |
212 void demux_close_rawdv(demuxer_t* demuxer) | |
213 { | |
214 rawdv_frames_t *frames = (rawdv_frames_t *)demuxer->priv; | |
215 | |
216 if(frames==0) | |
217 return; | |
218 free(frames); | |
219 } | |
220 | |
221 #endif |