static void *consumer_thread(void *);
static void consumer_write_JPEG(char * path, uint8_t **vBuffer, mlt_profile myProfile);
-int convertYCBCRtoRGB(int y1, int cb, int cr, int y2, int * target_rgb);
+int convertYCBCRtoRGB(int y1, int cb, int cr, int y2, uint8_t * target_rgb);
/*****************************************************************************************************
****************************************** SDI Master Consumer **************************************
parent->stop = consumer_stop;
parent->is_stopped = consumer_is_stopped;
- // Set explizit to zero or other value
+ // Set explicit to zero or other value
int i, j;
for (i = 0; i < MAX_AUDIO_STREAMS; i++) {
for (j = 0; j < MAX_AUDIO_SAMPLES; j++) {
* @param target pointer
* @return 0 upon success
**/
-int convertYCBCRtoRGB(int y1, int cb, int cr, int y2, int * target_rgb) {
+int convertYCBCRtoRGB(int y1, int cb, int cr, int y2, uint8_t * target_rgb) {
#ifdef WITH_JPEG
- uint32_t tmp = 0;
+ if(y1 > 235)
+ y1 = 235;
+ if(y1 < 16)
+ y1 = 16;
+
+ if(y2 > 235)
+ y2 = 235;
+ if(y2 < 16)
+ y2 = 16;
+
+ if(cr > 240)
+ cr = 240;
+ if(cr < 16)
+ cr = 16;
+
+ if(cb > 240)
+ cb = 240;
+ if(cb < 16)
+ cb = 16;
+
uint8_t r1, g1, b1, r2, g2, b2;
//pointer to current output buffer position
uint8_t * target_pointer = target_rgb;
- // colorconversion for first pixel and output to rgb buffer
- /* B1 */
- tmp = 1.164 * (y1 - 16) + 2.017 * (cb - 128);
- if (tmp > 255)
- tmp = 255;
- if (tmp < 0)
- tmp = 0;
- b1 = tmp;
-
- /* G1 */
- tmp = 1.164 * (y1 - 16) - 0.813 * (cr - 128) - 0.392 * (cb - 128);
- if (tmp > 255)
- tmp = 255;
- if (tmp < 0)
- tmp = 0;
- g1 = tmp;
-
- /* R1 */
- tmp = 1.164 * (y1 - 16) + 1.596 * (cr - 128);
- if (tmp > 255)
- tmp = 255;
- if (tmp < 0)
- tmp = 0;
- r1 = tmp;
-
- // colorconversion for second pixel and output to rgb buffer
- /* B2 */
- tmp = 1.164 * (y2 - 16) + 2.017 * (cb - 128);
- if (tmp > 255)
- tmp = 255;
- if (tmp < 0)
- tmp = 0;
- b2 = tmp;
-
- /* G2 */
- tmp = 1.164 * (y2 - 16) - 0.813 * (cr - 128) - 0.392 * (cb - 128);
- if (tmp > 255)
- tmp = 255;
- if (tmp < 0)
- tmp = 0;
- g2 = tmp;
-
- /* R2 */
- tmp = 1.164 * (y2 - 16) + 1.596 * (cr - 128);
- if (tmp > 255)
- tmp = 255;
- if (tmp < 0)
- tmp = 0;
- r2 = tmp;
-
- // r=y+1.5958*v;
- // g=y-0.39173*u-0.81290*v;
- // b=y+2.017*u;
+ r1 = y1 + 1.402 * (cr - 128);
+ g1 = y1 - 0.34414 * (cb - 128) - 0.71414 * (cr - 128);
+ b1 = y1 + 1.772 * (cb - 128);
+
+
+ r2 = y2 + 1.402 * (cr - 128);
+ g2 = y2 - 0.34414 * (cb - 128) - 0.71414 *(cr - 128);
+ b2 = y2 + 1.772 * (cb - 128);
+
*target_pointer++ = r1;
*target_pointer++ = g1;
info.blanking = blanking;
// set pack methode for SDI word conversion
- //pack = pack8;
+ pack = pack8;
//pack = pack10;
- pack = pack_v210;
+ //pack = pack_v210;
// check format
if (myProfile->width == 1920 && myProfile->height == 1080 && myProfile->frame_rate_num == 30 && myProfile->frame_rate_den == 1 && myProfile->progressive
&& myProfile->progressive == 0) {
info.fmt = &FMT_480i5994;
} else {
- printf("Consumer gets unknown format: %s", myProfile->description);
+ printf("Consumer got unknown format: %s", myProfile->description);
info.fmt = &FMT_576i50;
}
printf("Consumer use format: %s\nProfile: %i %i %i %i %i\n", myProfile->description, myProfile->width, myProfile->height, myProfile->frame_rate_num,
myProfile->frame_rate_den, myProfile->progressive);
- // Check if the format support own blanking (note: model 193 support currently only active video at the video device file)
+ // Check if the format supports own blanking (note: model 193 supports currently only active video at the video device file)
if (info.blanking && info.fmt != &FMT_576i50) {
- printf("SDI consumer doesn't support blanking(HANC) for this configurred SD board and SDI format. Try arguemnt: blanking=false\n");
+ printf("SDI consumer doesn't support blanking(HANC) for the configured SD board and SDI format. Try argument: blanking=false\n");
return EXIT_FAILURE;
}
printf("SDI consumer use video device file: %s\n", device_file_video);
}
- // Check if seperat device file for audio must use
+ // Check if we have to use a separate device file for audio
if (device_file_audio != NULL) {
// open file handler for audio output
if ((fh_sdi_audio = open(device_file_audio, O_WRONLY | O_CREAT, 0777)) == -1) {
perror(NULL);
- printf("\ncould not open audio output destination: %s\n", device_file_audio);
+ printf("\nCould not open audio output destination: %s\n", device_file_audio);
return EXIT_FAILURE;
}
printf("SDI consumer use audio device file: %s\n", device_file_audio);
AESChannelStatusBitArray[i] = 0;
/**
- * Professionel Format - Channel Status Bits
+ * Professional Format - Channel Status Bits
**/
////// Byte 0 //////
AESChannelStatusBitArray[0] = 1; // professional format
AESChannelStatusBitArray[5] = 0; // locked
- AESChannelStatusBitArray[6] = 0; // sample frequncy Fs: [01]48kHz, [10]44kHz, [11]32kHz
+ AESChannelStatusBitArray[6] = 0; // sample frequency Fs: [01]48kHz, [10]44kHz, [11]32kHz
AESChannelStatusBitArray[7] = 1; // ^
////// Byte 1 //////
AESChannelStatusBitArray[8] = 0; // channel mode: [0000] not indicated, [0001]2channels, [0010]1channel mono, ...
}
}
- // hack/overwrite because we use default the pack_v210() not as befor the pack10()
//(*10/8 because we store (TOTAL_SAMPLES*TOTAL_LINES) words with 10 bit in this 8 bit array) )
if (info.fmt == &FMT_576i50 && info.blanking) {
sdi_frame_size = info.fmt->samples_per_line * 10 / 8 * info.fmt->lines_per_frame;
// Write the complete frame to output
// The "while" is necessary because the sdi device file does not take the complete frame at once
written_bytes = 0;
- while (bytes < sdi_frame_size) {
+ while (bytes < sdi_frame_size)
+ {
if ((written_bytes = write(fh_sdi_video, data + bytes, sdi_frame_size - bytes)) < 0) {
fprintf(stderr, "\nunable to write SDI video.\n");
return -1;
}
bytes += written_bytes;
+ }
- // Check for events of the SDI board
- unsigned int val;
- if (ioctl(fh_sdi_video, SDI_IOC_TXGETEVENTS, &val) < 0) {
- // Maybe this is not an SDI device...
- fprintf(stderr, "SDI VIDEO output:");
- perror("unable to get the transmitter event flags");
- } else if (val) {
- if (val & SDI_EVENT_TX_BUFFER) {
- printf("SDI VIDEO driver transmit buffer queue underrun "
- "detected.\n");
- }
- if (val & SDI_EVENT_TX_FIFO) {
- printf("SDI VIDEO onboard transmit FIFO underrun detected.\n");
- // TODO react
- }
- if (val & SDI_EVENT_TX_DATA) {
- printf("SDI VIDEO transmit data change detected.\n");
- }
+ // Check for events of the SDI board
+ unsigned int val;
+ if (ioctl(fh_sdi_video, SDI_IOC_TXGETEVENTS, &val) < 0) {
+ // Maybe this is not an SDI device...
+ //fprintf(stderr, "SDI VIDEO output:");
+ //perror("unable to get the transmitter event flags");
+ } else if (val) {
+ if (val & SDI_EVENT_TX_BUFFER) {
+ printf("SDI VIDEO driver transmit buffer queue underrun "
+ "detected.\n");
+ fflush(stdout);
+ }
+ if (val & SDI_EVENT_TX_FIFO) {
+ printf("SDI VIDEO onboard transmit FIFO underrun detected.\n");
+ fflush(stdout);
+ }
+ if (val & SDI_EVENT_TX_DATA) {
+ printf("SDI VIDEO transmit data change detected.\n");
+ fflush(stdout);
}
- fflush(stdout);
}
+
+
// if available write audio data
if (fh_sdi_audio) {
sample_number++;
-// // Check for events of the SDI board (only firmware 0.9)
-// unsigned int val;
-// if (ioctl(fh_sdi_audio, SDI_IOC_TXGETEVENTS, &val) < 0) {
-// //Maybe this is not an SDI device...
-// fprintf(stderr, "SDI AUDIO output:");
-// perror("unable to get the transmitter event flags");
-// } else if (val) {
-// if (val & SDI_EVENT_TX_BUFFER) {
-// printf("SDI AUDIO driver transmit buffer queue underrun "
-// "detected.\n");
-// }
-// if (val & SDI_EVENT_TX_FIFO) {
-// printf("SDI AUDIO onboard transmit FIFO underrun detected.\n");
-// //TODO react
-// }
-// if (val & SDI_EVENT_TX_DATA) {
-// printf("SDI AUDIO transmit data change detected.\n");
-// }
-// }
+ // Check for events of the SDI audio device
+ unsigned int val;
+ if (ioctl(fh_sdi_audio, SDIAUDIO_IOC_TXGETEVENTS, &val) < 0) {
+ //Maybe this is not an SDI device...
+ // fprintf(stderr, "SDI AUDIO output:");
+ // perror("unable to get the transmitter event flags");
+ } else if (val) {
+ if (val & SDIAUDIO_EVENT_TX_BUFFER) {
+ printf("SDI AUDIO driver transmit buffer queue underrun "
+ "detected.\n");
+ }
+ if (val & SDIAUDIO_EVENT_TX_FIFO) {
+ printf("SDI AUDIO onboard transmit FIFO underrun detected.\n");
+ //TODO react
+ }
+ if (val & SDIAUDIO_EVENT_TX_DATA) {
+ printf("SDI AUDIO transmit data change detected.\n");
+ }
+ }
}
}
*p++ = info->xyz->sav;
//#########################################################################################
+
+ // Because we skip the first line of video, it can happen that we read too far in the buffer
+ if (active_video_line >= info->fmt->active_lines_per_frame) {
+ active_video_line = info->fmt->active_lines_per_frame - 1; // in SD PAL was set 575
+ }
+ //Index of the start of the current line in the video_buffer
+ int start_of_current_line = active_video_line * info->fmt->active_samples_per_line;
+
// If VBlank then fill the line with 0x200 and 0x040 (total black)
switch (active) {
default:
// shift "<< 2" because 8 bit data in 10 bit word
- // Because we skip the first line of video, it can happen that we read too far in the buffer
- if (active_video_line >= info->fmt->active_lines_per_frame) {
- active_video_line = info->fmt->active_lines_per_frame - 1; // in SD PAL was set 575
- }
-
- *p = video_buffer[(active_video_line * 1440) + ((p - 288) - buf) + 1] << 2; // Cb
+ *p = video_buffer[start_of_current_line + ((p - 288) - buf) + 1] << 2; // Cb
p++;
if (*(p - 1) < 0x040)
*(p - 1) = 0x040; // check values
if (*(p - 1) > 0x3c0)
*(p - 1) = 0x3c0;
- *p = video_buffer[(active_video_line * 1440) + ((p - 288) - buf) - 1] << 2; // Y1
+ *p = video_buffer[start_of_current_line + ((p - 288) - buf) - 1] << 2; // Y1
p++;
if (*(p - 1) < 0x040)
*(p - 1) = 0x040;
if (*(p - 1) > 0x3ac)
*(p - 1) = 0x3ac;
- *p = video_buffer[(active_video_line * 1440) + ((p - 288) - buf) + 1] << 2; // Cr
+ *p = video_buffer[start_of_current_line + ((p - 288) - buf) + 1] << 2; // Cr
p++;
if (*(p - 1) < 0x040)
*(p - 1) = 0x040;
if (*(p - 1) > 0x3c0)
*(p - 1) = 0x3c0;
- *p = video_buffer[(active_video_line * 1440) + ((p - 288) - buf) - 1] << 2; // Y2
+ *p = video_buffer[start_of_current_line + ((p - 288) - buf) - 1] << 2; // Y2
p++;
if (*(p - 1) < 0x040)
*(p - 1) = 0x040;
uint16_t *p = buf, *endp, ln;
uint16_t samples = info->blanking ? info->fmt->samples_per_line : info->fmt->active_samples_per_line;
+
+ if (active_video_line >= info->fmt->active_lines_per_frame) {
+ active_video_line = info->fmt->active_lines_per_frame - 1;
+ }
+
+ int start_of_current_line = active_video_line * info->fmt->active_samples_per_line;
+
+
if (info->blanking) {
// write line with TRS(EAV) ANC(audio) TRS(SAV) activeVideo(CbY1CrY2)
while (p < (buf + samples)) {
- if (active_video_line >= info->fmt->active_lines_per_frame) {
- active_video_line = info->fmt->active_lines_per_frame - 1;
- }
-
- // sample = (active_video_line * info->fmt->active_samples_per_line) + (p - buf) + 1;
- // *p++ = sample > 1440 ? 735 : (video_buffer[sample] << 2);
- // sample = (active_video_line * info->fmt->active_samples_per_line) + (p - buf) - 1;
- // *p++ = sample > 1440 ? 335 : (video_buffer[sample] << 2);
- // sample = (active_video_line * info->fmt->active_samples_per_line) + (p - buf) + 1;
- // *p++ = sample > 1440 ? 793 : (video_buffer[sample] << 2);
- // sample = (active_video_line * info->fmt->active_samples_per_line) + (p - buf) - 1;
- // *p++ = sample > 1440 ? 335 : (video_buffer[sample] << 2);
- *p = video_buffer[(active_video_line * info->fmt->active_samples_per_line) + (p - buf) + 1] << 2; // Cb
+ *p = video_buffer[start_of_current_line + (p - buf) + 1] << 2; // Cb
p++;
- // check values, but need manny resources
+ //check values, this needs a lot of resources
// if (*(p - 1) < 0x040)
// *(p - 1) = 0x040;
// if (*(p - 1) > 0x3c0)
// *(p - 1) = 0x3c0;
//
- *p = video_buffer[(active_video_line * info->fmt->active_samples_per_line) + (p - buf) - 1] << 2; // Y1
+ *p = video_buffer[start_of_current_line + (p - buf) - 1] << 2; // Y1
p++;
// if (*(p - 1) < 0x040)
// *(p - 1) = 0x040;
// if (*(p - 1) > 0x3ac)
// *(p - 1) = 0x3ac;
//
- *p = video_buffer[(active_video_line * info->fmt->active_samples_per_line) + (p - buf) + 1] << 2; // Cr
+ *p = video_buffer[start_of_current_line + (p - buf) + 1] << 2; // Cr
p++;
// if (*(p - 1) < 0x040)
// *(p - 1) = 0x040;
// if (*(p - 1) > 0x3c0)
// *(p - 1) = 0x3c0;
//
- *p = video_buffer[(active_video_line * info->fmt->active_samples_per_line) + (p - buf) - 1] << 2; // Y2
+ *p = video_buffer[start_of_current_line + (p - buf) - 1] << 2; // Y2
p++;
// if (*(p - 1) < 0x040)
// *(p - 1) = 0x040;